From 9b89b473d337dd2853b601f58a15775cc3dfd277 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Thu, 9 Jul 2026 13:27:24 -0500 Subject: [PATCH 01/61] wip: pause PersonaPlex CPU audio parity at sampler fix --- .planning/.continue-here.md | 135 ++ .planning/HANDOFF.json | 70 + .../debug/moshi-personaplex-audio-parity.md | 40 + CMakeLists.txt | 1 + docs/benchmarking.md | 6 + src/emel/gguf/loader/detail.hpp | 42 + src/emel/kernel/aarch64/actions.hpp | 915 ++++--- src/emel/kernel/aarch64/guards.hpp | 235 +- src/emel/kernel/aarch64/sm.hpp | 65 +- src/emel/kernel/any.hpp | 2 +- src/emel/kernel/detail.hpp | 254 +- src/emel/model/data.hpp | 11 + src/emel/model/moshi/detail.cpp | 270 ++- src/emel/speech/codec/mimi/detail.cpp | 127 +- src/emel/speech/codec/mimi/detail.hpp | 16 +- src/emel/speech/codec/mimi/guards.hpp | 8 +- .../speech/codec/mimi/quantizer/guards.hpp | 5 +- src/emel/speech/generator/moshi/actions.hpp | 952 ++++++++ src/emel/speech/generator/moshi/any.hpp | 9 + src/emel/speech/generator/moshi/context.hpp | 90 + src/emel/speech/generator/moshi/detail.hpp | 38 + src/emel/speech/generator/moshi/errors.hpp | 22 + src/emel/speech/generator/moshi/events.hpp | 311 +++ .../generator/moshi/executor/actions.hpp | 1864 +++++++++++++++ .../speech/generator/moshi/executor/any.hpp | 43 + .../generator/moshi/executor/context.hpp | 87 + .../generator/moshi/executor/detail.hpp | 307 +++ .../generator/moshi/executor/errors.hpp | 17 + .../generator/moshi/executor/events.hpp | 159 ++ .../generator/moshi/executor/guards.hpp | 1942 +++++++++++++++ .../speech/generator/moshi/executor/sm.hpp | 943 ++++++++ src/emel/speech/generator/moshi/guards.hpp | 686 ++++++ src/emel/speech/generator/moshi/sm.hpp | 741 ++++++ tests/kernel/aarch64_tests.cpp | 344 ++- tests/kernel/lifecycle_tests.cpp | 26 + tests/model/moshi/binding_tests.cpp | 217 +- tests/models/README.md | 13 +- tests/models/mimi-tiny-f16.gguf | 2 +- tests/models/mimi-tiny-q8.gguf | 2 +- tests/models/mimi-tiny.gguf | 2 +- tests/models/moshi-tiny-config.json | 10 + tests/models/moshi-tiny-lm.gguf | 4 +- tests/speech/codec/mimi_detail_tests.cpp | 19 +- tests/speech/codec/mimi_lifecycle_tests.cpp | 131 +- .../generator/moshi_lifecycle_tests.cpp | 2100 +++++++++++++++++ .../moshi_gguf_convert.cpython-314.pyc | Bin 0 -> 100099 bytes .../moshi_make_tiny_fixture.cpython-314.pyc | Bin 0 -> 25632 bytes tools/bench/moshi_gguf_convert.py | 437 +++- tools/bench/moshi_make_tiny_fixture.py | 8 +- tools/paritychecker/CMakeLists.txt | 13 +- tools/paritychecker/parity_engines.cpp | 12 +- 51 files changed, 12761 insertions(+), 992 deletions(-) create mode 100644 .planning/.continue-here.md create mode 100644 .planning/HANDOFF.json create mode 100644 .planning/debug/moshi-personaplex-audio-parity.md create mode 100644 src/emel/speech/generator/moshi/actions.hpp create mode 100644 src/emel/speech/generator/moshi/any.hpp create mode 100644 src/emel/speech/generator/moshi/context.hpp create mode 100644 src/emel/speech/generator/moshi/detail.hpp create mode 100644 src/emel/speech/generator/moshi/errors.hpp create mode 100644 src/emel/speech/generator/moshi/events.hpp create mode 100644 src/emel/speech/generator/moshi/executor/actions.hpp create mode 100644 src/emel/speech/generator/moshi/executor/any.hpp create mode 100644 src/emel/speech/generator/moshi/executor/context.hpp create mode 100644 src/emel/speech/generator/moshi/executor/detail.hpp create mode 100644 src/emel/speech/generator/moshi/executor/errors.hpp create mode 100644 src/emel/speech/generator/moshi/executor/events.hpp create mode 100644 src/emel/speech/generator/moshi/executor/guards.hpp create mode 100644 src/emel/speech/generator/moshi/executor/sm.hpp create mode 100644 src/emel/speech/generator/moshi/guards.hpp create mode 100644 src/emel/speech/generator/moshi/sm.hpp create mode 100644 tests/speech/generator/moshi_lifecycle_tests.cpp create mode 100644 tools/bench/__pycache__/moshi_gguf_convert.cpython-314.pyc create mode 100644 tools/bench/__pycache__/moshi_make_tiny_fixture.cpython-314.pyc diff --git a/.planning/.continue-here.md b/.planning/.continue-here.md new file mode 100644 index 00000000..3bb58e2e --- /dev/null +++ b/.planning/.continue-here.md @@ -0,0 +1,135 @@ +--- +context: default +phase: persona-plex-moshi-cpu-audio-parity +task: 2 +total_tasks: 5 +status: in_progress +last_updated: 2026-07-09T18:25:29.229Z +--- + +# BLOCKING CONSTRAINTS - Read Before Anything Else + +> These constraints were discovered through failed E2E attempts. Acknowledge each one before proceeding. + +- [ ] CPU ONLY: run both PersonaPlex implementations on CPU; do not load or select Metal. +- [ ] REAL PERSONAPLEX: use the PersonaPlex Moshi LM and NATF0 voice, not a generic Moshi model. +- [ ] SAME INPUT AND SEED: use `build/moshi_e2e/say_input_24k.wav` and seed 1234 for both implementations. +- [ ] EXPLICIT CONTROL FLOW: runtime behavior choices belong in guards and transitions, not actions or detail helpers. +- [ ] NO HARDCODED MODEL POLICY: model-specific inference values belong in GGUF metadata or an injected configuration. +- [ ] AUDIBLE PROOF: do not call the goal complete until EMEL writes intelligible speech and the output WAV has been played. + +**Do not proceed until all boxes are checked.** + +## Critical Anti-Patterns + +| Pattern | Description | Severity | Prevention Mechanism | +|---------|-------------|----------|---------------------| +| Mathematically equivalent sampling shortcut | EMEL sorted raw logits and exponentiated only top-k values, while moshi.cpp materializes a full-card f32 GGML softmax first. The shortcut changed a near-tie seeded winner. | blocking | Add a reference-vector regression and implement the exact f32 sampling sequence before another full E2E. | +| Global sampling state | `std::srand`/`std::rand` is process-global, so executor instances are not isolated. | blocking | Replace it with actor-owned or injected reference-compatible RNG state without changing the seed-1234 draw sequence. | +| Partial run presented as audio proof | The latest EMEL CPU run stopped during voice prefill and wrote no WAV. | blocking | Require a completed output file, token/audio comparison, objective audio checks, and `afplay` before completion. | +| Model policy in scratch harness | The scratch E2E currently assigns temperatures/top-k/seed directly. | advisory | Put PersonaPlex defaults in converted GGUF metadata or expose a deliberate injected configuration; keep seed as a test parameter. | + + + +Branch: `feature/moshi-personaplex-e2e`. + +The worktree is committed as an intentionally partial WIP. The earliest deterministic mismatch is generated frame 0, audio codebook 2: + +- EMEL: `1049,488,572,1471,...` +- moshi.cpp: `1049,488,1632,1533,...` + +RNG draw counts align: 25 forced-text draws, then 250 draws per audio codebook. Codebooks 0 and 1 match. Codebook 2 logits are close, so this is a numerical sampling boundary rather than a wrong model or shifted RNG stream. + +The concrete arithmetic defect fixed immediately before this handoff was that `soft_max_row_ggml` had no arm64 NEON path and fell back to scalar `expf`. `src/emel/kernel/detail.hpp` now ports GGML's NEON `v_expf` polynomial and four-lane reduction order. `tests/kernel/lifecycle_tests.cpp` checks 16 exact f32 bit patterns obtained from the linked GGML CPU reference. The test first failed on 10 lanes and now passes 16/16. + +The Moshi sampler itself is still incomplete: it sorts raw logits, exponentiates only top-k values, and uses global `std::rand`. moshi.cpp instead scales all logits by inverse temperature, computes a full-card GGML f32 softmax, argsorts those probabilities, divides top-k probabilities by exponential draws, and takes argmax. + + + + + +Completed tasks: + +- Reproduced current CPU-only frame-0 divergence with rebuilt EMEL binary. +- Confirmed PersonaPlex model, voice, seed, and RNG draw counts align. +- Removed temporary generator/executor debug-phase public API and modeled depformer weight selection with explicit guards/transitions. +- Added the arm64 GGML softmax regression before the fix. +- Ported GGML's arm64 NEON `v_expf` and reduction order. +- Verified `kernel_soft_max_row_matches_ggml_arm64_neon_bits`: 16/16 assertions pass. +- Earlier speech-shard test run passed before the final softmax change. + + + + + +- Add a failing reference-vector test for the exact top-k exponential sampler. +- Replace raw-logit top-k sampling with full-card GGML-compatible f32 softmax probabilities. +- Replace process-global RNG state with an actor-owned or injected reference-compatible source while preserving seed-1234 Darwin `rand` draws. +- Move/expose PersonaPlex sampling policy through GGUF metadata or injected configuration; do not leave model policy hardcoded in the maintained harness. +- Rebuild the scratch E2E binary and rerun only until frame 0 to verify codebook-2 alignment. +- Complete CPU-only moshi.cpp and EMEL runs from the same `say` WAV. +- Compare token traces and WAVs quantitatively, confirm intelligible speech, and play the EMEL WAV with `afplay`. +- Run speech and kernel tests, domain-boundary checks, README symbolic-reference review, and scoped quality gates. + + + + + +- The fixed seed is 1234; keep it identical in both lanes. +- The maintained runtime must be EMEL-owned; moshi.cpp/GGML is reference-only. +- The earliest mismatch, not downstream WAV quality, drives debugging. +- The arm64 softmax fix belongs in the shared kernel numeric layer. +- Sampling validation and route selection must remain explicit state-machine behavior. + + + + + +- Technical: exact full-card sampling parity is not implemented yet. +- Technical: a complete EMEL CPU E2E is slow and no output WAV currently exists. +- Human action: none required to continue; the model artifacts and input WAV are already under `build/`. + + + +## Required Reading (in order) + +1. `.planning/debug/moshi-personaplex-audio-parity.md` - persistent evidence log. +2. `AGENTS.md` - actor, control-flow, test, and reference-lane constraints. +3. `docs/rules/sml.rules.md` - authoritative Stateforward.SML semantics. +4. `src/emel/speech/generator/moshi/executor/actions.hpp` - current sampler and graph arithmetic. +5. `src/emel/speech/generator/moshi/executor/guards.hpp` and `sm.hpp` - explicit route decisions. +6. `src/emel/kernel/detail.hpp` - newly fixed arm64 GGML softmax path. +7. `build/moshi_cpp_reference/src/src/moshi/utils/sampling.h` - reference sampling sequence. + +## Critical Anti-Patterns (do NOT repeat these) + +- Do not use Metal or Metal library paths in the reference lane. +- Do not substitute a generic Moshi model for PersonaPlex. +- Do not debug downstream Mimi audio before generated token parity is repaired. +- Do not hide sampling mode, clamp, validation, fallback, or RNG selection in actions/detail helpers. +- Do not interpret a partial prefill trace as completed speech generation. + +## Infrastructure State + +- No E2E, reference, server, build, or diagnostic process is intentionally left running. +- Current test build: `build/zig`, configured with `EMEL_TEST_SHARDS=kernel_and_graph,speech`. +- Passing focused test: + `build/zig/emel_tests_bin --test-case=kernel_soft_max_row_matches_ggml_arm64_neon_bits --no-skip`. +- Same input: `build/moshi_e2e/say_input_24k.wav`. +- EMEL models: `build/moshi_reference/mimi-e351c8d8-125-emel.gguf`, `model-q4_k-emel.gguf`, and `voices/NATF0-emel.gguf`. +- Reference binary: `build/moshi_cpp_reference/build/bin/personaplex -d CPU --threads 1`. +- Scratch E2E source/binary under `build/` is intentionally not a maintained repo entry. + + + +The strongest remaining hypothesis is no longer model execution. EMEL and moshi.cpp depformer logits are close at codebook 2, and the arm64 softmax implementation was proven numerically different. The shared softmax kernel is now fixed. The next narrow experiment is the sampler pipeline itself. Do not spend another full CPU run until a reference-vector sampling test passes and the first generated frame can be stopped/compared quickly. + + + + + +Start with: add a failing sampler regression that uses deterministic logits and seed 1234, then make EMEL follow moshi.cpp exactly: f32 inverse-temperature scaling, full-card `soft_max_row_ggml`, top-k over materialized probabilities, reference exponential draws, and f32 probability/divisor argmax. Keep RNG ownership injected or actor-local and keep every runtime behavior choice in guards/transitions. + +Handoff goal: make EMEL PersonaPlex Moshi generate real, intelligible speech end to end on CPU from the same macOS `say` WAV as moshi.cpp, with seed 1234 producing closely matching token/audio behavior, no hidden control flow, no hardcoded model inference policy, and an output WAV that is quantitatively checked and played for the user. + + diff --git a/.planning/HANDOFF.json b/.planning/HANDOFF.json new file mode 100644 index 00000000..b0845335 --- /dev/null +++ b/.planning/HANDOFF.json @@ -0,0 +1,70 @@ +{ + "version": "1.0", + "timestamp": "2026-07-09T18:25:29.229Z", + "phase": null, + "phase_name": "PersonaPlex Moshi CPU audio parity", + "phase_dir": null, + "plan": 1, + "task": 2, + "total_tasks": 5, + "status": "paused", + "completed_tasks": [ + { + "id": 1, + "name": "Reproduce the first EMEL/reference divergence on current CPU-only binaries", + "status": "done", + "commit": "this WIP commit" + }, + { + "id": 2, + "name": "Fix the first proven numerical or sampling divergence without hidden control flow", + "status": "in_progress", + "progress": "Added and passed a bit-exact arm64 GGML NEON softmax regression; full-card GGML-compatible sampling and actor-owned RNG remain unfinished." + } + ], + "remaining_tasks": [ + { + "id": 3, + "name": "Run matched-seed moshi.cpp and EMEL PersonaPlex E2E from the same macOS say WAV", + "status": "not_started" + }, + { + "id": 4, + "name": "Compare token traces and generated WAVs, then confirm and play intelligible speech", + "status": "not_started" + }, + { + "id": 5, + "name": "Run scoped tests, domain checks, README sync, and quality gates", + "status": "not_started" + } + ], + "blockers": [ + { + "description": "EMEL still diverges from moshi.cpp at generated frame 0 audio codebook 2 because the sampler does not yet materialize the same full-card f32 softmax probability buffer before top-k exponential sampling.", + "type": "technical", + "workaround": "Continue from the passing arm64 softmax regression and port the reference sampling arithmetic before rerunning the slow CPU E2E." + } + ], + "human_actions_pending": [], + "decisions": [ + { + "decision": "Keep all reference and EMEL runs CPU-only.", + "rationale": "The user explicitly rejected Metal and requires CPU parity.", + "phase": null + }, + { + "decision": "Treat frame 0 codebook 2 as the earliest authoritative failure boundary.", + "rationale": "With seed 1234 and aligned draw counts, both implementations emit 1049,488 before EMEL chooses 572 and moshi.cpp chooses 1632.", + "phase": null + }, + { + "decision": "Port GGML's arm64 NEON v_expf arithmetic before changing model execution.", + "rationale": "The prior EMEL softmax used scalar expf on arm64 and differed from actual GGML output by 1-2 ULPs; the new regression now matches all 16 reference lanes bit-for-bit.", + "phase": null + } + ], + "uncommitted_files": [], + "next_action": "Replace Moshi sampling's raw-logit shortcut with the reference sequence: f32 inverse-temperature scaling, full-card soft_max_row_ggml, top-k on materialized probabilities, reference exponential draws, and f32 probability/divisor argmax; add a failing sampler regression first and keep behavior choices in guards/transitions.", + "context_notes": "The goal is incomplete. No EMEL output WAV has completed. A fresh CPU run reproduced the same codebook-2 mismatch and stopped during voice prefill at frame 10. The arm64 softmax regression passes, but the full sampling path, injected/model-owned inference configuration, actor-owned RNG, matched E2E run, audible verification, and final gates remain." +} diff --git a/.planning/debug/moshi-personaplex-audio-parity.md b/.planning/debug/moshi-personaplex-audio-parity.md new file mode 100644 index 00000000..72dc21f9 --- /dev/null +++ b/.planning/debug/moshi-personaplex-audio-parity.md @@ -0,0 +1,40 @@ +--- +status: investigating +trigger: "Make EMEL PersonaPlex Moshi generate real speech end to end from the same macOS say WAV input as moshi.cpp, with fixed-seed reference comparison showing closely matching audio/token behavior and an output WAV the user can hear. CPU only." +created: 2026-07-09 +updated: 2026-07-09 +--- + +# Moshi PersonaPlex Audio Parity + +## Symptoms + +- expected: EMEL and moshi.cpp consume the same macOS `say` WAV with seed 1234 and produce closely matching PersonaPlex speech audio and token behavior on CPU. +- actual: moshi.cpp produces speech, while completed earlier EMEL attempts produced non-speech; the latest EMEL run reached generation frame 24 but was interrupted before writing a WAV. +- errors: no runtime error was reported; the incomplete run stopped without an output WAV. +- timeline: the current feature branch adds the EMEL Moshi generator and PersonaPlex model binding; parity has not yet been demonstrated. +- reproduction: run `build/emel_moshi_say_e2e_current` with the converted Mimi, Moshi LM, NATF0 voice, and `build/moshi_e2e/say_input_24k.wav` inputs. + +## Current Focus + +- hypothesis: EMEL diverges from moshi.cpp in depformer token generation after the first matching codebook token, before Mimi decoding. +- test: complete deterministic CPU traces for both implementations and compare the first generated frame codebook by codebook. +- expecting: the first mismatching codebook identifies the earliest model execution or sampling phase that needs correction. +- next_action: gather initial evidence +- reasoning_checkpoint: +- tdd_checkpoint: + +## Evidence + +- timestamp: 2026-07-09T13:00:00-05:00 + observation: the latest EMEL log completed 51 voice-prefill frames, 12 prompt-prefill frames, and generated frames 0 through 24, but no WAV exists. + implication: PersonaPlex setup and generation dispatch run on CPU; audible output and parity remain unproven. + +## Eliminated + +## Resolution + +- root_cause: +- fix: +- verification: +- files_changed: diff --git a/CMakeLists.txt b/CMakeLists.txt index 88ea8e16..804c3046 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,6 +189,7 @@ if(EMEL_ENABLE_TESTS) tests/diarization/sortformer/transformer/lifecycle_tests.cpp tests/speech/codec/mimi_detail_tests.cpp tests/speech/codec/mimi_lifecycle_tests.cpp + tests/speech/generator/moshi_lifecycle_tests.cpp tests/speech/encoder/whisper/lifecycle_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp diff --git a/docs/benchmarking.md b/docs/benchmarking.md index df890ed8..66ad0b93 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -344,6 +344,12 @@ fetch pinned artifacts and produce the EMEL-lane GGUF, but it does not build, li moshi.cpp reference lane. the guard is meant to fail if the maintained EMEL Moshi model contract rejects a valid converted LM GGUF. +the converted GGUF owns the PersonaPlex inference contract. the converter writes +`moshi.lm.inference.dep_q`, `moshi.lm.inference.pre_text_silence_frames`, +`moshi.lm.inference.post_text_silence_frames`, and `moshi.lm.inference.prompt_tokens`; EMEL loads +those fields from model metadata instead of hardcoding prompt or delayed-codebook constants in the +generator. + the default model discovery order is: - `--model` diff --git a/src/emel/gguf/loader/detail.hpp b/src/emel/gguf/loader/detail.hpp index 5b9de0e3..e8e58ed8 100644 --- a/src/emel/gguf/loader/detail.hpp +++ b/src/emel/gguf/loader/detail.hpp @@ -83,6 +83,11 @@ inline constexpr ggml_type_layout ggml_layout(const uint32_t type) noexcept { } } +inline constexpr bool is_emel_packed_q4_k_x8_type( + const uint32_t type) noexcept { + return type == 41u || type == 42u; +} + inline constexpr uint8_t gguf_scalar_size(const uint32_t type) noexcept { switch (type) { case constants::gguf_type_uint8: @@ -127,6 +132,35 @@ inline bool multiply_u64(const uint64_t lhs, const uint64_t rhs, uint64_t & out) return true; } +inline emel::error::type compute_emel_packed_q4_k_x8_data_size( + const std::array &dims, const uint32_t n_dims, + uint64_t &data_size_out) noexcept { + constexpr uint64_t k_block_cols = 256u; + constexpr uint64_t k_group_rows = 8u; + constexpr uint64_t k_group_block_bytes = 1152u; + if (n_dims < 2u || n_dims > constants::max_tensor_dims || + (dims[0] % k_block_cols) != 0u) { + return cast_loader_error(error::model_invalid); + } + + uint64_t rows = 1u; + for (uint32_t dim_index = 1u; dim_index < n_dims; ++dim_index) { + if (!multiply_u64(rows, dims[dim_index], rows)) { + return cast_loader_error(error::capacity); + } + } + + const uint64_t block_count = dims[0] / k_block_cols; + const uint64_t group_count = (rows + k_group_rows - 1u) / k_group_rows; + uint64_t groups_and_blocks = 0u; + if (!multiply_u64(group_count, block_count, groups_and_blocks) || + !multiply_u64(groups_and_blocks, k_group_block_bytes, data_size_out)) { + return cast_loader_error(error::capacity); + } + + return cast_loader_error(error::none); +} + inline bool pad_to_alignment(const uint64_t value, const uint32_t alignment, uint64_t & out) noexcept { @@ -217,6 +251,9 @@ inline bool valid_gguf_type(const uint32_t type) noexcept { } inline bool valid_ggml_type(const uint32_t type) noexcept { + if (is_emel_packed_q4_k_x8_type(type)) { + return true; + } const ggml_type_layout layout = ggml_layout(type); return layout.block_size != 0u && layout.type_size != 0u; } @@ -339,6 +376,11 @@ inline emel::error::type compute_tensor_data_size(const std::array return cast_loader_error(error::model_invalid); } + if (is_emel_packed_q4_k_x8_type(type)) { + return compute_emel_packed_q4_k_x8_data_size(dims, n_dims, + data_size_out); + } + const ggml_type_layout layout = ggml_layout(type); const uint64_t first_dim = n_dims == 0u ? 1u : dims[0]; if ((first_dim % layout.block_size) != 0u) { diff --git a/src/emel/kernel/aarch64/actions.hpp b/src/emel/kernel/aarch64/actions.hpp index 85b4855c..7b439cf9 100644 --- a/src/emel/kernel/aarch64/actions.hpp +++ b/src/emel/kernel/aarch64/actions.hpp @@ -946,17 +946,18 @@ inline bool can_run_neon_mul_mat_q6_vector_q8_rhs_request( request.src0.nb[0] == 1u && row_bytes != 0u && request.src0.nb[1] == row_bytes && request.src0.nb[2] == row_bytes * m && - request.src0.nb[3] == request.src0.nb[2] && - request.src1.nb[0] == 1u && rhs_row_bytes != 0u && - request.src1.nb[1] == rhs_row_bytes && + request.src0.nb[3] == request.src0.nb[2] && request.src1.nb[0] == 1u && + rhs_row_bytes != 0u && request.src1.nb[1] == rhs_row_bytes && request.src1.nb[2] == rhs_row_bytes && request.src1.nb[3] == rhs_row_bytes && is_dense_contiguous(request.dst); } -inline bool can_use_neon_mul_mat_q6_vector_q8_rhs( - const event::op_mul_mat &request, const bool neon_available) noexcept { - return neon_available && can_run_neon_mul_mat_q6_vector_q8_rhs_request(request); +inline bool +can_use_neon_mul_mat_q6_vector_q8_rhs(const event::op_mul_mat &request, + const bool neon_available) noexcept { + return neon_available && + can_run_neon_mul_mat_q6_vector_q8_rhs_request(request); } inline bool neon_q5_0_vector_supported() noexcept { @@ -1147,16 +1148,16 @@ inline bool can_run_neon_mul_mat_q8_0_vector_q8_rhs_request( request.src0.nb[0] == 1u && row_bytes != 0u && request.src0.nb[1] == row_bytes && request.src0.nb[2] == row_bytes * m && - request.src0.nb[3] == request.src0.nb[2] && - request.src1.nb[0] == 1u && rhs_row_bytes != 0u && - request.src1.nb[1] == rhs_row_bytes && + request.src0.nb[3] == request.src0.nb[2] && request.src1.nb[0] == 1u && + rhs_row_bytes != 0u && request.src1.nb[1] == rhs_row_bytes && request.src1.nb[2] == rhs_row_bytes && request.src1.nb[3] == rhs_row_bytes && is_dense_contiguous(request.dst); } -inline bool can_use_neon_mul_mat_q8_0_vector_q8_rhs( - const event::op_mul_mat &request, const bool neon_available) noexcept { +inline bool +can_use_neon_mul_mat_q8_0_vector_q8_rhs(const event::op_mul_mat &request, + const bool neon_available) noexcept { return neon_available && can_run_neon_mul_mat_q8_0_vector_q8_rhs_request(request); } @@ -1292,8 +1293,6 @@ inline bool can_use_neon_mul_mat_q8_0_packed_bl8_full_groups( 0u; } - - inline bool can_use_neon_mul_mat_q8_0_packed_bl8_tail_safe( const event::op_mul_mat &request, const bool neon_available) noexcept { return can_use_neon_mul_mat_q8_0_packed_bl8(request, neon_available) && @@ -1399,6 +1398,35 @@ inline bool can_run_neon_mul_mat_q4_vector_packed_q8_rhs_request( is_dense_contiguous(request.dst); } +inline bool can_run_neon_mul_mat_q4_vector_packed_f32_rhs_request( + const event::op_mul_mat &request, const uint8_t packed_dtype) noexcept { + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + const uint64_t group_count = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_count(m); + const size_t group_bytes = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_storage_bytes(k); + return k != 0u && m != 0u && block_count != 0u && + block_count <= ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS && + request.src1.ne[0] == 1u && request.src1.ne[1] == k && + request.dst.ne[0] == 1u && request.dst.ne[1] == m && + request.src0.ne[2] == 1u && request.src0.ne[3] == 1u && + request.src1.ne[2] == 1u && request.src1.ne[3] == 1u && + request.dst.ne[2] == 1u && request.dst.ne[3] == 1u && + ::emel::kernel::detail::dtype_code(request.src0.type) == + packed_dtype && + ::emel::kernel::detail::dtype_code(request.src1.type) == + ::emel::kernel::detail::dtype_f32 && + ::emel::kernel::detail::dtype_code(request.dst.type) == + ::emel::kernel::detail::dtype_f32 && + request.src0.nb[0] == 1u && group_bytes != 0u && + request.src0.nb[1] == group_bytes && + request.src0.nb[2] == group_bytes * group_count && + request.src0.nb[3] == request.src0.nb[2] && + is_dense_contiguous(request.src1) && is_dense_contiguous(request.dst); +} + inline bool can_run_neon_mul_mat_q4_vector_q8_rhs_request( const event::op_mul_mat &request) noexcept { const uint64_t k = request.src0.ne[0]; @@ -1425,14 +1453,39 @@ inline bool can_run_neon_mul_mat_q4_vector_q8_rhs_request( request.src0.nb[0] == 1u && row_bytes != 0u && request.src0.nb[1] == row_bytes && request.src0.nb[2] == row_bytes * m && - request.src0.nb[3] == request.src0.nb[2] && - request.src1.nb[0] == 1u && rhs_row_bytes != 0u && - request.src1.nb[1] == rhs_row_bytes && + request.src0.nb[3] == request.src0.nb[2] && request.src1.nb[0] == 1u && + rhs_row_bytes != 0u && request.src1.nb[1] == rhs_row_bytes && request.src1.nb[2] == rhs_row_bytes && request.src1.nb[3] == rhs_row_bytes && is_dense_contiguous(request.dst); } +inline bool can_run_neon_mul_mat_q4_vector_f32_rhs_request( + const event::op_mul_mat &request) noexcept { + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + const size_t row_bytes = ::emel::kernel::detail::quantized_row_storage_bytes( + ::emel::kernel::detail::dtype_q4_k, k); + return k != 0u && m != 0u && block_count != 0u && + block_count <= ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS && + request.src1.ne[0] == 1u && request.src1.ne[1] == k && + request.dst.ne[0] == 1u && request.dst.ne[1] == m && + request.src0.ne[2] == 1u && request.src0.ne[3] == 1u && + request.src1.ne[2] == 1u && request.src1.ne[3] == 1u && + request.dst.ne[2] == 1u && request.dst.ne[3] == 1u && + ::emel::kernel::detail::dtype_code(request.src0.type) == + ::emel::kernel::detail::dtype_q4_k && + ::emel::kernel::detail::dtype_code(request.src1.type) == + ::emel::kernel::detail::dtype_f32 && + ::emel::kernel::detail::dtype_code(request.dst.type) == + ::emel::kernel::detail::dtype_f32 && + request.src0.nb[0] == 1u && row_bytes != 0u && + request.src0.nb[1] == row_bytes && + request.src0.nb[2] == row_bytes * m && + request.src0.nb[3] == request.src0.nb[2] && + is_dense_contiguous(request.src1) && is_dense_contiguous(request.dst); +} inline bool can_run_neon_mul_mat_q6_vector_packed_q8_rhs_request( const event::op_mul_mat &request) noexcept { @@ -1467,7 +1520,6 @@ inline bool can_run_neon_mul_mat_q6_vector_packed_q8_rhs_request( is_dense_contiguous(request.dst); } - inline bool can_run_neon_mul_mat_q6_vector_prepared_q8_rhs_request( const event::op_mul_mat &request) noexcept { const uint64_t k = request.src0.ne[0]; @@ -1522,13 +1574,33 @@ inline bool can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl8( request, ::emel::kernel::detail::dtype_q4_k_x8_bl8); } -inline bool can_use_neon_mul_mat_q4_vector_q8_rhs( +inline bool can_use_neon_mul_mat_q4_vector_packed_f32_rhs_bl4( + const event::op_mul_mat &request, const bool neon_available) noexcept { + return neon_available && neon_q4_vector_packed_supported() && + can_run_neon_mul_mat_q4_vector_packed_f32_rhs_request( + request, ::emel::kernel::detail::dtype_q4_k_x8_bl4); +} + +inline bool can_use_neon_mul_mat_q4_vector_packed_f32_rhs_bl8( const event::op_mul_mat &request, const bool neon_available) noexcept { + return neon_available && neon_q4_vector_packed_supported() && + can_run_neon_mul_mat_q4_vector_packed_f32_rhs_request( + request, ::emel::kernel::detail::dtype_q4_k_x8_bl8); +} + +inline bool +can_use_neon_mul_mat_q4_vector_q8_rhs(const event::op_mul_mat &request, + const bool neon_available) noexcept { return neon_available && neon_q4_vector_q8_rhs_supported() && can_run_neon_mul_mat_q4_vector_q8_rhs_request(request); } - +inline bool +can_use_neon_mul_mat_q4_vector_f32_rhs(const event::op_mul_mat &request, + const bool neon_available) noexcept { + return neon_available && neon_q4_vector_q8_rhs_supported() && + can_run_neon_mul_mat_q4_vector_f32_rhs_request(request); +} inline bool can_use_neon_mul_mat_q6_vector_packed_q8_rhs( const event::op_mul_mat &request, const bool neon_available) noexcept { @@ -1536,7 +1608,6 @@ inline bool can_use_neon_mul_mat_q6_vector_packed_q8_rhs( can_run_neon_mul_mat_q6_vector_packed_q8_rhs_request(request); } - inline bool can_use_neon_mul_mat_q6_vector_prepared_q8_rhs( const event::op_mul_mat &request, const bool neon_available) noexcept { #if defined(__ARM_FEATURE_MATMUL_INT8) @@ -1555,7 +1626,6 @@ inline bool can_use_neon_mul_mat_q6_vector_prepared_q8_rhs_i8mm( can_run_neon_mul_mat_q6_vector_prepared_q8_rhs_request(request); } - inline bool can_run_neon_mul_mat_argmax_q6_vector_prepared_q8_rhs_request( const event::op_mul_mat_argmax &request) noexcept { const uint64_t k = request.src0.ne[0]; @@ -1655,6 +1725,38 @@ inline bool can_run_neon_mul_mat_argmax_q6_vector_packed_q8_rhs_request( ::emel::kernel::aarch64::detail::is_dense_contiguous(request.dst); } +inline bool can_run_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_request( + const event::op_mul_mat_argmax &request, + const uint8_t packed_dtype) noexcept { + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + const uint64_t group_count = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_count(m); + const size_t group_bytes = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_storage_bytes(k); + return request.index_out != nullptr && k != 0u && m != 0u && + block_count != 0u && + block_count <= ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS && + request.src1.ne[0] == 1u && request.src1.ne[1] == k && + request.dst.ne[0] == 1u && request.dst.ne[1] == 1u && + request.src0.ne[2] == 1u && request.src0.ne[3] == 1u && + request.src1.ne[2] == 1u && request.src1.ne[3] == 1u && + request.dst.ne[2] == 1u && request.dst.ne[3] == 1u && + ::emel::kernel::detail::dtype_code(request.src0.type) == + packed_dtype && + ::emel::kernel::detail::dtype_code(request.src1.type) == + ::emel::kernel::detail::dtype_f32 && + ::emel::kernel::detail::dtype_code(request.dst.type) == + ::emel::kernel::detail::dtype_f32 && + request.src0.nb[0] == 1u && group_bytes != 0u && + request.src0.nb[1] == group_bytes && + request.src0.nb[2] == group_bytes * group_count && + request.src0.nb[3] == request.src0.nb[2] && + ::emel::kernel::aarch64::detail::is_dense_contiguous(request.src1) && + ::emel::kernel::aarch64::detail::is_dense_contiguous(request.dst); +} + inline bool can_use_neon_mul_mat_argmax_q6_vector_packed_q8_rhs( const event::op_mul_mat_argmax &request, const bool neon_available) noexcept { @@ -1662,6 +1764,22 @@ inline bool can_use_neon_mul_mat_argmax_q6_vector_packed_q8_rhs( can_run_neon_mul_mat_argmax_q6_vector_packed_q8_rhs_request(request); } +inline bool can_use_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4( + const event::op_mul_mat_argmax &request, + const bool neon_available) noexcept { + return neon_available && neon_q4_vector_packed_supported() && + can_run_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_request( + request, ::emel::kernel::detail::dtype_q4_k_x8_bl4); +} + +inline bool can_use_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8( + const event::op_mul_mat_argmax &request, + const bool neon_available) noexcept { + return neon_available && neon_q4_vector_packed_supported() && + can_run_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_request( + request, ::emel::kernel::detail::dtype_q4_k_x8_bl8); +} + inline bool can_use_neon_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm( const event::op_mul_mat_argmax &request, const bool neon_available) noexcept { @@ -2649,42 +2767,41 @@ inline float dot_q4_k_q8_k_block_neon( const uint8_t *q4 = lhs.qs.data(); const int8_t *q8 = rhs.qs.data(); - int32x4_t low_acc = vdupq_n_s32(0); - int32x4_t high_acc = vdupq_n_s32(0); + int32_t low_sum = 0; + int32_t high_sum = 0; for (uint64_t group = 0; group < (::emel::kernel::detail::quant::QK_K / 64u); ++group) { - const uint8x16_t q4bits0 = vld1q_u8(q4 + 0u); - const uint8x16_t q4bits1 = vld1q_u8(q4 + 16u); - const int8x16_t q8bytes0 = vld1q_s8(q8 + 0u); - const int8x16_t q8bytes1 = vld1q_s8(q8 + 16u); - const int8x16_t q8bytes2 = vld1q_s8(q8 + 32u); - const int8x16_t q8bytes3 = vld1q_s8(q8 + 48u); - - const int8x16_t q4low0 = vreinterpretq_s8_u8(vandq_u8(q4bits0, m4b)); - const int8x16_t q4low1 = vreinterpretq_s8_u8(vandq_u8(q4bits1, m4b)); - const int8x16_t q4high0 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits0, 4)); - const int8x16_t q4high1 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits1, 4)); - - const int32_t low_scale = static_cast(scales[group * 2u + 0u]); - const int32_t high_scale = static_cast(scales[group * 2u + 1u]); - low_acc = - vmlaq_n_s32(low_acc, vdotq_s32(zero, q4low0, q8bytes0), low_scale); - low_acc = - vmlaq_n_s32(low_acc, vdotq_s32(zero, q4low1, q8bytes1), low_scale); - high_acc = - vmlaq_n_s32(high_acc, vdotq_s32(zero, q4high0, q8bytes2), high_scale); - high_acc = - vmlaq_n_s32(high_acc, vdotq_s32(zero, q4high1, q8bytes3), high_scale); - + const uint8x16x2_t q4bits = load_u8x16x2(q4); q4 += 32u; - q8 += 64u; + + int8x16x2_t q8bytes = vld1q_s8_x2(q8); + q8 += 32u; + const int8x16_t q4low0 = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); + const int8x16_t q4low1 = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); + const int32x4_t low_dot = + vdotq_s32(vdotq_s32(zero, q4low0, q8bytes.val[0]), q4low1, + q8bytes.val[1]); + low_sum += vaddvq_s32(low_dot) * + static_cast(scales[group * 2u + 0u]); + + q8bytes = vld1q_s8_x2(q8); + q8 += 32u; + const int8x16_t q4high0 = + vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + const int8x16_t q4high1 = + vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + const int32x4_t high_dot = + vdotq_s32(vdotq_s32(zero, q4high0, q8bytes.val[0]), q4high1, + q8bytes.val[1]); + high_sum += vaddvq_s32(high_dot) * + static_cast(scales[group * 2u + 1u]); } - const int32_t isum = vaddvq_s32(vaddq_s32(low_acc, high_acc)); const float d = ::emel::kernel::detail::quant::fp16_to_fp32(lhs.d) * rhs.d; const float dmin = ::emel::kernel::detail::quant::fp16_to_fp32(lhs.dmin) * rhs.d; - return d * static_cast(isum) - dmin * static_cast(min_sum); + return d * static_cast(low_sum + high_sum) - + dmin * static_cast(min_sum); #endif } @@ -2713,105 +2830,8 @@ dot_q4_k_q8_k_2rows_neon(const ::emel::kernel::detail::quant::block_q4_k *lhs0, out[0] = dot_q4_k_q8_k_row_neon(lhs0, rhs, block_count); out[1] = dot_q4_k_q8_k_row_neon(lhs1, rhs, block_count); #else - const uint8x16_t m4b = vdupq_n_u8(0x0fu); - const int32x4_t zero = vdupq_n_s32(0); - float sum0 = 0.0f; - float sum1 = 0.0f; - - for (uint64_t block = 0; block < block_count; ++block) { - const auto &lhs_block0 = lhs0[block]; - const auto &lhs_block1 = lhs1[block]; - uint32_t decoded_words0[4] = {}; - uint32_t decoded_words1[4] = {}; - decode_q4_k_scales_words(lhs_block0, decoded_words0); - decode_q4_k_scales_words(lhs_block1, decoded_words1); - - const auto *scales0 = reinterpret_cast(decoded_words0); - const auto *scales1 = reinterpret_cast(decoded_words1); - const auto *mins0 = reinterpret_cast(decoded_words0 + 2); - const auto *mins1 = reinterpret_cast(decoded_words1 + 2); - const int16x8_t q8_pair_sums = - vpaddq_s16(vld1q_s16(rhs[block].bsums.data()), - vld1q_s16(rhs[block].bsums.data() + 8)); - const int32_t min_sum0 = q4_k_min_sum_neon(mins0, q8_pair_sums); - const int32_t min_sum1 = q4_k_min_sum_neon(mins1, q8_pair_sums); - - const uint8_t *q40 = lhs_block0.qs.data(); - const uint8_t *q41 = lhs_block1.qs.data(); - const int8_t *q8 = rhs[block].qs.data(); - int32x4_t low_acc0 = vdupq_n_s32(0); - int32x4_t high_acc0 = vdupq_n_s32(0); - int32x4_t low_acc1 = vdupq_n_s32(0); - int32x4_t high_acc1 = vdupq_n_s32(0); - - for (uint64_t group = 0; - group < (::emel::kernel::detail::quant::QK_K / 64u); ++group) { - const uint8x16_t q4bits00 = vld1q_u8(q40 + 0u); - const uint8x16_t q4bits01 = vld1q_u8(q40 + 16u); - const uint8x16_t q4bits10 = vld1q_u8(q41 + 0u); - const uint8x16_t q4bits11 = vld1q_u8(q41 + 16u); - const int8x16_t q8bytes0 = vld1q_s8(q8 + 0u); - const int8x16_t q8bytes1 = vld1q_s8(q8 + 16u); - const int8x16_t q8bytes2 = vld1q_s8(q8 + 32u); - const int8x16_t q8bytes3 = vld1q_s8(q8 + 48u); - - const int8x16_t q4low00 = vreinterpretq_s8_u8(vandq_u8(q4bits00, m4b)); - const int8x16_t q4low01 = vreinterpretq_s8_u8(vandq_u8(q4bits01, m4b)); - const int8x16_t q4high00 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits00, 4)); - const int8x16_t q4high01 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits01, 4)); - const int8x16_t q4low10 = vreinterpretq_s8_u8(vandq_u8(q4bits10, m4b)); - const int8x16_t q4low11 = vreinterpretq_s8_u8(vandq_u8(q4bits11, m4b)); - const int8x16_t q4high10 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits10, 4)); - const int8x16_t q4high11 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits11, 4)); - - const int32_t low_scale0 = static_cast(scales0[group * 2u + 0u]); - const int32_t high_scale0 = - static_cast(scales0[group * 2u + 1u]); - const int32_t low_scale1 = static_cast(scales1[group * 2u + 0u]); - const int32_t high_scale1 = - static_cast(scales1[group * 2u + 1u]); - - low_acc0 = - vmlaq_n_s32(low_acc0, vdotq_s32(zero, q4low00, q8bytes0), low_scale0); - low_acc0 = - vmlaq_n_s32(low_acc0, vdotq_s32(zero, q4low01, q8bytes1), low_scale0); - high_acc0 = vmlaq_n_s32(high_acc0, vdotq_s32(zero, q4high00, q8bytes2), - high_scale0); - high_acc0 = vmlaq_n_s32(high_acc0, vdotq_s32(zero, q4high01, q8bytes3), - high_scale0); - low_acc1 = - vmlaq_n_s32(low_acc1, vdotq_s32(zero, q4low10, q8bytes0), low_scale1); - low_acc1 = - vmlaq_n_s32(low_acc1, vdotq_s32(zero, q4low11, q8bytes1), low_scale1); - high_acc1 = vmlaq_n_s32(high_acc1, vdotq_s32(zero, q4high10, q8bytes2), - high_scale1); - high_acc1 = vmlaq_n_s32(high_acc1, vdotq_s32(zero, q4high11, q8bytes3), - high_scale1); - - q40 += 32u; - q41 += 32u; - q8 += 64u; - } - - const int32_t isum0 = vaddvq_s32(vaddq_s32(low_acc0, high_acc0)); - const int32_t isum1 = vaddvq_s32(vaddq_s32(low_acc1, high_acc1)); - const float rhs_d = rhs[block].d; - const float d0 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block0.d) * rhs_d; - const float d1 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block1.d) * rhs_d; - const float dmin0 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block0.dmin) * rhs_d; - const float dmin1 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block1.dmin) * rhs_d; - sum0 += - d0 * static_cast(isum0) - dmin0 * static_cast(min_sum0); - sum1 += - d1 * static_cast(isum1) - dmin1 * static_cast(min_sum1); - } - - out[0] = sum0; - out[1] = sum1; + out[0] = dot_q4_k_q8_k_row_neon(lhs0, rhs, block_count); + out[1] = dot_q4_k_q8_k_row_neon(lhs1, rhs, block_count); #endif } @@ -2828,177 +2848,40 @@ dot_q4_k_q8_k_4rows_neon(const ::emel::kernel::detail::quant::block_q4_k *lhs0, out[2] = dot_q4_k_q8_k_row_neon(lhs2, rhs, block_count); out[3] = dot_q4_k_q8_k_row_neon(lhs3, rhs, block_count); #else - const uint8x16_t m4b = vdupq_n_u8(0x0fu); - const int32x4_t zero = vdupq_n_s32(0); - float sum0 = 0.0f; - float sum1 = 0.0f; - float sum2 = 0.0f; - float sum3 = 0.0f; + out[0] = dot_q4_k_q8_k_row_neon(lhs0, rhs, block_count); + out[1] = dot_q4_k_q8_k_row_neon(lhs1, rhs, block_count); + out[2] = dot_q4_k_q8_k_row_neon(lhs2, rhs, block_count); + out[3] = dot_q4_k_q8_k_row_neon(lhs3, rhs, block_count); +#endif +} - for (uint64_t block = 0; block < block_count; ++block) { - const auto &lhs_block0 = lhs0[block]; - const auto &lhs_block1 = lhs1[block]; - const auto &lhs_block2 = lhs2[block]; - const auto &lhs_block3 = lhs3[block]; - uint32_t decoded_words0[4] = {}; - uint32_t decoded_words1[4] = {}; - uint32_t decoded_words2[4] = {}; - uint32_t decoded_words3[4] = {}; - decode_q4_k_scales_words(lhs_block0, decoded_words0); - decode_q4_k_scales_words(lhs_block1, decoded_words1); - decode_q4_k_scales_words(lhs_block2, decoded_words2); - decode_q4_k_scales_words(lhs_block3, decoded_words3); - - const auto *scales0 = reinterpret_cast(decoded_words0); - const auto *scales1 = reinterpret_cast(decoded_words1); - const auto *scales2 = reinterpret_cast(decoded_words2); - const auto *scales3 = reinterpret_cast(decoded_words3); - const auto *mins0 = reinterpret_cast(decoded_words0 + 2); - const auto *mins1 = reinterpret_cast(decoded_words1 + 2); - const auto *mins2 = reinterpret_cast(decoded_words2 + 2); - const auto *mins3 = reinterpret_cast(decoded_words3 + 2); - const int16x8_t q8_pair_sums = - vpaddq_s16(vld1q_s16(rhs[block].bsums.data()), - vld1q_s16(rhs[block].bsums.data() + 8)); - const int32_t min_sum0 = q4_k_min_sum_neon(mins0, q8_pair_sums); - const int32_t min_sum1 = q4_k_min_sum_neon(mins1, q8_pair_sums); - const int32_t min_sum2 = q4_k_min_sum_neon(mins2, q8_pair_sums); - const int32_t min_sum3 = q4_k_min_sum_neon(mins3, q8_pair_sums); - - const uint8_t *q40 = lhs_block0.qs.data(); - const uint8_t *q41 = lhs_block1.qs.data(); - const uint8_t *q42 = lhs_block2.qs.data(); - const uint8_t *q43 = lhs_block3.qs.data(); - const int8_t *q8 = rhs[block].qs.data(); - int32x4_t low_acc0 = vdupq_n_s32(0); - int32x4_t high_acc0 = vdupq_n_s32(0); - int32x4_t low_acc1 = vdupq_n_s32(0); - int32x4_t high_acc1 = vdupq_n_s32(0); - int32x4_t low_acc2 = vdupq_n_s32(0); - int32x4_t high_acc2 = vdupq_n_s32(0); - int32x4_t low_acc3 = vdupq_n_s32(0); - int32x4_t high_acc3 = vdupq_n_s32(0); - - for (uint64_t group = 0; - group < (::emel::kernel::detail::quant::QK_K / 64u); ++group) { - const uint8x16_t q4bits00 = vld1q_u8(q40 + 0u); - const uint8x16_t q4bits01 = vld1q_u8(q40 + 16u); - const uint8x16_t q4bits10 = vld1q_u8(q41 + 0u); - const uint8x16_t q4bits11 = vld1q_u8(q41 + 16u); - const uint8x16_t q4bits20 = vld1q_u8(q42 + 0u); - const uint8x16_t q4bits21 = vld1q_u8(q42 + 16u); - const uint8x16_t q4bits30 = vld1q_u8(q43 + 0u); - const uint8x16_t q4bits31 = vld1q_u8(q43 + 16u); - const int8x16_t q8bytes0 = vld1q_s8(q8 + 0u); - const int8x16_t q8bytes1 = vld1q_s8(q8 + 16u); - const int8x16_t q8bytes2 = vld1q_s8(q8 + 32u); - const int8x16_t q8bytes3 = vld1q_s8(q8 + 48u); - - const int8x16_t q4low00 = vreinterpretq_s8_u8(vandq_u8(q4bits00, m4b)); - const int8x16_t q4low01 = vreinterpretq_s8_u8(vandq_u8(q4bits01, m4b)); - const int8x16_t q4high00 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits00, 4)); - const int8x16_t q4high01 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits01, 4)); - const int8x16_t q4low10 = vreinterpretq_s8_u8(vandq_u8(q4bits10, m4b)); - const int8x16_t q4low11 = vreinterpretq_s8_u8(vandq_u8(q4bits11, m4b)); - const int8x16_t q4high10 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits10, 4)); - const int8x16_t q4high11 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits11, 4)); - const int8x16_t q4low20 = vreinterpretq_s8_u8(vandq_u8(q4bits20, m4b)); - const int8x16_t q4low21 = vreinterpretq_s8_u8(vandq_u8(q4bits21, m4b)); - const int8x16_t q4high20 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits20, 4)); - const int8x16_t q4high21 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits21, 4)); - const int8x16_t q4low30 = vreinterpretq_s8_u8(vandq_u8(q4bits30, m4b)); - const int8x16_t q4low31 = vreinterpretq_s8_u8(vandq_u8(q4bits31, m4b)); - const int8x16_t q4high30 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits30, 4)); - const int8x16_t q4high31 = vreinterpretq_s8_u8(vshrq_n_u8(q4bits31, 4)); - - const int32_t low_scale0 = static_cast(scales0[group * 2u + 0u]); - const int32_t high_scale0 = - static_cast(scales0[group * 2u + 1u]); - const int32_t low_scale1 = static_cast(scales1[group * 2u + 0u]); - const int32_t high_scale1 = - static_cast(scales1[group * 2u + 1u]); - const int32_t low_scale2 = static_cast(scales2[group * 2u + 0u]); - const int32_t high_scale2 = - static_cast(scales2[group * 2u + 1u]); - const int32_t low_scale3 = static_cast(scales3[group * 2u + 0u]); - const int32_t high_scale3 = - static_cast(scales3[group * 2u + 1u]); - - low_acc0 = - vmlaq_n_s32(low_acc0, vdotq_s32(zero, q4low00, q8bytes0), low_scale0); - low_acc0 = - vmlaq_n_s32(low_acc0, vdotq_s32(zero, q4low01, q8bytes1), low_scale0); - high_acc0 = vmlaq_n_s32(high_acc0, vdotq_s32(zero, q4high00, q8bytes2), - high_scale0); - high_acc0 = vmlaq_n_s32(high_acc0, vdotq_s32(zero, q4high01, q8bytes3), - high_scale0); - low_acc1 = - vmlaq_n_s32(low_acc1, vdotq_s32(zero, q4low10, q8bytes0), low_scale1); - low_acc1 = - vmlaq_n_s32(low_acc1, vdotq_s32(zero, q4low11, q8bytes1), low_scale1); - high_acc1 = vmlaq_n_s32(high_acc1, vdotq_s32(zero, q4high10, q8bytes2), - high_scale1); - high_acc1 = vmlaq_n_s32(high_acc1, vdotq_s32(zero, q4high11, q8bytes3), - high_scale1); - low_acc2 = - vmlaq_n_s32(low_acc2, vdotq_s32(zero, q4low20, q8bytes0), low_scale2); - low_acc2 = - vmlaq_n_s32(low_acc2, vdotq_s32(zero, q4low21, q8bytes1), low_scale2); - high_acc2 = vmlaq_n_s32(high_acc2, vdotq_s32(zero, q4high20, q8bytes2), - high_scale2); - high_acc2 = vmlaq_n_s32(high_acc2, vdotq_s32(zero, q4high21, q8bytes3), - high_scale2); - low_acc3 = - vmlaq_n_s32(low_acc3, vdotq_s32(zero, q4low30, q8bytes0), low_scale3); - low_acc3 = - vmlaq_n_s32(low_acc3, vdotq_s32(zero, q4low31, q8bytes1), low_scale3); - high_acc3 = vmlaq_n_s32(high_acc3, vdotq_s32(zero, q4high30, q8bytes2), - high_scale3); - high_acc3 = vmlaq_n_s32(high_acc3, vdotq_s32(zero, q4high31, q8bytes3), - high_scale3); - - q40 += 32u; - q41 += 32u; - q42 += 32u; - q43 += 32u; - q8 += 64u; - } +inline void decode_q4_k_x8_6bit_scales_neon(const uint8_t *scales_in, + int16x8_t &mins_out, + int16x8_t &scales_out) noexcept { +#if !(defined(__aarch64__) && defined(__ARM_NEON)) + (void)scales_in; + (void)mins_out; + (void)scales_out; +#else + constexpr uint32_t kmask1 = 0x3f3f3f3fu; + constexpr uint32_t kmask2 = 0x0f0f0f0fu; + constexpr uint32_t kmask3 = 0x03030303u; + std::array sm = {}; + std::memcpy(sm.data(), scales_in, 12u); - const int32_t isum0 = vaddvq_s32(vaddq_s32(low_acc0, high_acc0)); - const int32_t isum1 = vaddvq_s32(vaddq_s32(low_acc1, high_acc1)); - const int32_t isum2 = vaddvq_s32(vaddq_s32(low_acc2, high_acc2)); - const int32_t isum3 = vaddvq_s32(vaddq_s32(low_acc3, high_acc3)); - const float rhs_d = rhs[block].d; - const float d0 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block0.d) * rhs_d; - const float d1 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block1.d) * rhs_d; - const float d2 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block2.d) * rhs_d; - const float d3 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block3.d) * rhs_d; - const float dmin0 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block0.dmin) * rhs_d; - const float dmin1 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block1.dmin) * rhs_d; - const float dmin2 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block2.dmin) * rhs_d; - const float dmin3 = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs_block3.dmin) * rhs_d; - sum0 += - d0 * static_cast(isum0) - dmin0 * static_cast(min_sum0); - sum1 += - d1 * static_cast(isum1) - dmin1 * static_cast(min_sum1); - sum2 += - d2 * static_cast(isum2) - dmin2 * static_cast(min_sum2); - sum3 += - d3 * static_cast(isum3) - dmin3 * static_cast(min_sum3); - } + const uint32_t mins_0_3 = sm[1] & kmask1; + const uint32_t mins_4_7 = + ((sm[2] >> 4u) & kmask2) | (((sm[1] >> 6u) & kmask3) << 4u); + const uint32x2_t mins_u32 = {mins_0_3, mins_4_7}; + mins_out = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins_u32))); - out[0] = sum0; - out[1] = sum1; - out[2] = sum2; - out[3] = sum3; + std::array scales_u32 = {}; + scales_u32[0] = sm[0] & kmask1; + scales_u32[1] = + (sm[2] & kmask2) | (((sm[0] >> 6u) & kmask3) << 4u); + std::array scales_bytes = {}; + std::memcpy(scales_bytes.data(), scales_u32.data(), scales_bytes.size()); + scales_out = vmovl_s8(vld1_s8(scales_bytes.data())); #endif } @@ -3053,12 +2936,9 @@ inline void dot_q4_k_x8_q8_k_group_bl4_neon( std::array q4sb_scales = {}; for (uint64_t half = 0; half < 2u; ++half) { const uint8_t *prepared = - q4_block.scales.data() + - ((sb * 2u + half) * ::emel::kernel::detail::quant::Q4_K_X8_ROWS * - 2u); - q4sb_mins[half] = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(prepared))); - q4sb_scales[half] = vreinterpretq_s16_u16(vmovl_u8( - vld1_u8(prepared + ::emel::kernel::detail::quant::Q4_K_X8_ROWS))); + q4_block.scales.data() + sb * 24u + half * 12u; + decode_q4_k_x8_6bit_scales_neon(prepared, q4sb_mins[half], + q4sb_scales[half]); } std::array q8_qs = {}; @@ -3222,12 +3102,9 @@ inline void dot_q4_k_x8_q8_k_group_bl8_neon( std::array q4sb_scales = {}; for (uint64_t half = 0; half < 2u; ++half) { const uint8_t *prepared = - q4_block.scales.data() + - ((sb * 2u + half) * ::emel::kernel::detail::quant::Q4_K_X8_ROWS * - 2u); - q4sb_mins[half] = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(prepared))); - q4sb_scales[half] = vreinterpretq_s16_u16(vmovl_u8( - vld1_u8(prepared + ::emel::kernel::detail::quant::Q4_K_X8_ROWS))); + q4_block.scales.data() + sb * 24u + half * 12u; + decode_q4_k_x8_6bit_scales_neon(prepared, q4sb_mins[half], + q4sb_scales[half]); } const uint8_t *q4_base = @@ -3394,12 +3271,9 @@ inline void dot_q4_k_x8_q8_k_group_bl8_x4_neon( std::array q4sb_scales = {}; for (uint64_t half = 0; half < 2u; ++half) { const uint8_t *prepared = - q4_block.scales.data() + - ((sb * 2u + half) * ::emel::kernel::detail::quant::Q4_K_X8_ROWS * - 2u); - q4sb_mins[half] = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(prepared))); - q4sb_scales[half] = vreinterpretq_s16_u16(vmovl_u8( - vld1_u8(prepared + ::emel::kernel::detail::quant::Q4_K_X8_ROWS))); + q4_block.scales.data() + sb * 24u + half * 12u; + decode_q4_k_x8_6bit_scales_neon(prepared, q4sb_mins[half], + q4sb_scales[half]); } const uint8_t *q4_base = @@ -3587,12 +3461,9 @@ inline void dot_q4_k_x8_q8_k_group_bl8_x8_neon( std::array q4sb_scales = {}; for (uint64_t half = 0; half < 2u; ++half) { const uint8_t *prepared = - q4_block.scales.data() + - ((sb * 2u + half) * ::emel::kernel::detail::quant::Q4_K_X8_ROWS * - 2u); - q4sb_mins[half] = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(prepared))); - q4sb_scales[half] = vreinterpretq_s16_u16(vmovl_u8( - vld1_u8(prepared + ::emel::kernel::detail::quant::Q4_K_X8_ROWS))); + q4_block.scales.data() + sb * 24u + half * 12u; + decode_q4_k_x8_6bit_scales_neon(prepared, q4sb_mins[half], + q4sb_scales[half]); } const uint8_t *q4_base = @@ -5668,6 +5539,108 @@ inline void execute_neon_mul_mat_argmax_q6_vector_packed_q8_rhs_unchecked( #endif } +inline void execute_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4_unchecked( + const event::op_mul_mat_argmax &request) noexcept { +#if !(defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD)) + (void)request; +#else + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + std::array<::emel::kernel::detail::quant::block_q8_k, + ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS> + q8_blocks = {}; + ::emel::kernel::detail::quant::quantize_row_q8_k_strided( + static_cast(request.src1.data), 1u, q8_blocks.data(), + static_cast(k)); + + const uint8_t *packed = static_cast(request.src0.data); + const size_t group_bytes = request.src0.nb[1]; + const uint64_t group_count = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_count(m); + float best_value = -std::numeric_limits::infinity(); + int32_t best_index = 0; + bool have_best = false; + for (uint64_t group = 0; group < group_count; ++group) { + const auto *group_ptr = + reinterpret_cast( + packed + group * group_bytes); + std::array group_out = + {}; + dot_q4_k_x8_q8_k_group_bl4_neon(group_ptr, q8_blocks.data(), block_count, + group_out.data()); + const uint64_t row_base = + group * ::emel::kernel::detail::quant::Q4_K_X8_ROWS; + const uint64_t rows_in_group = std::min( + static_cast(::emel::kernel::detail::quant::Q4_K_X8_ROWS), + m - row_base); + for (uint64_t row = 0; row < rows_in_group; ++row) { + const float value = group_out[row]; + if (!have_best || value > best_value) { + have_best = true; + best_value = value; + best_index = static_cast(row_base + row); + } + } + } + + static_cast(request.dst.data)[0] = best_value; + *request.index_out = best_index; +#endif +} + +inline void execute_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8_unchecked( + const event::op_mul_mat_argmax &request) noexcept { +#if !(defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD)) + (void)request; +#else + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + std::array<::emel::kernel::detail::quant::block_q8_k, + ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS> + q8_blocks = {}; + ::emel::kernel::detail::quant::quantize_row_q8_k_strided( + static_cast(request.src1.data), 1u, q8_blocks.data(), + static_cast(k)); + + const uint8_t *packed = static_cast(request.src0.data); + const size_t group_bytes = request.src0.nb[1]; + const uint64_t group_count = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_count(m); + float best_value = -std::numeric_limits::infinity(); + int32_t best_index = 0; + bool have_best = false; + for (uint64_t group = 0; group < group_count; ++group) { + const auto *group_ptr = + reinterpret_cast( + packed + group * group_bytes); + std::array group_out = + {}; + dot_q4_k_x8_q8_k_group_bl8_neon(group_ptr, q8_blocks.data(), block_count, + group_out.data()); + const uint64_t row_base = + group * ::emel::kernel::detail::quant::Q4_K_X8_ROWS; + const uint64_t rows_in_group = std::min( + static_cast(::emel::kernel::detail::quant::Q4_K_X8_ROWS), + m - row_base); + for (uint64_t row = 0; row < rows_in_group; ++row) { + const float value = group_out[row]; + if (!have_best || value > best_value) { + have_best = true; + best_value = value; + best_index = static_cast(row_base + row); + } + } + } + + static_cast(request.dst.data)[0] = best_value; + *request.index_out = best_index; +#endif +} + inline void execute_neon_mul_mat_q4_vector_packed_q8_rhs_bl4_unchecked( const event::op_mul_mat &request) noexcept { #if !(defined(__aarch64__) && defined(__ARM_NEON) && \ @@ -5705,6 +5678,47 @@ inline void execute_neon_mul_mat_q4_vector_packed_q8_rhs_bl4_unchecked( #endif } +inline void execute_neon_mul_mat_q4_vector_packed_f32_rhs_bl4_unchecked( + const event::op_mul_mat &request) noexcept { +#if !(defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD)) + (void)request; +#else + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + std::array<::emel::kernel::detail::quant::block_q8_k, + ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS> + q8_blocks = {}; + ::emel::kernel::detail::quant::quantize_row_q8_k_strided( + static_cast(request.src1.data), 1u, q8_blocks.data(), + static_cast(k)); + + const uint8_t *packed = static_cast(request.src0.data); + const size_t group_bytes = request.src0.nb[1]; + const uint64_t group_count = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_count(m); + float *dst = static_cast(request.dst.data); + for (uint64_t group = 0; group < group_count; ++group) { + const auto *group_ptr = + reinterpret_cast( + packed + group * group_bytes); + std::array group_out = + {}; + dot_q4_k_x8_q8_k_group_bl4_neon(group_ptr, q8_blocks.data(), block_count, + group_out.data()); + const uint64_t row_base = + group * ::emel::kernel::detail::quant::Q4_K_X8_ROWS; + const uint64_t rows_in_group = std::min( + static_cast(::emel::kernel::detail::quant::Q4_K_X8_ROWS), + m - row_base); + for (uint64_t row = 0; row < rows_in_group; ++row) { + dst[row_base + row] = group_out[row]; + } + } +#endif +} + inline void store_batch_major_group_results(const float *group_out, float *dst, const size_t dst_row_stride, @@ -5796,6 +5810,47 @@ inline void execute_neon_mul_mat_q4_vector_packed_q8_rhs_bl8_unchecked( #endif } +inline void execute_neon_mul_mat_q4_vector_packed_f32_rhs_bl8_unchecked( + const event::op_mul_mat &request) noexcept { +#if !(defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD)) + (void)request; +#else + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + std::array<::emel::kernel::detail::quant::block_q8_k, + ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS> + q8_blocks = {}; + ::emel::kernel::detail::quant::quantize_row_q8_k_strided( + static_cast(request.src1.data), 1u, q8_blocks.data(), + static_cast(k)); + + const uint8_t *packed = static_cast(request.src0.data); + const size_t group_bytes = request.src0.nb[1]; + const uint64_t group_count = + ::emel::kernel::detail::quant::packed_q4_k_x8_group_count(m); + float *dst = static_cast(request.dst.data); + for (uint64_t group = 0; group < group_count; ++group) { + const auto *group_ptr = + reinterpret_cast( + packed + group * group_bytes); + std::array group_out = + {}; + dot_q4_k_x8_q8_k_group_bl8_neon(group_ptr, q8_blocks.data(), block_count, + group_out.data()); + const uint64_t row_base = + group * ::emel::kernel::detail::quant::Q4_K_X8_ROWS; + const uint64_t rows_in_group = std::min( + static_cast(::emel::kernel::detail::quant::Q4_K_X8_ROWS), + m - row_base); + for (uint64_t row = 0; row < rows_in_group; ++row) { + dst[row_base + row] = group_out[row]; + } + } +#endif +} + inline void execute_neon_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4_unchecked( const event::op_mul_mat &request) noexcept { @@ -6707,6 +6762,70 @@ inline void execute_neon_mul_mat_q4_vector_q8_rhs_unchecked( #endif } +inline void execute_neon_mul_mat_q4_vector_f32_rhs_unchecked( + const event::op_mul_mat &request) noexcept { +#if !(defined(__aarch64__) || defined(__ARM_NEON)) + (void)request; +#else + const uint64_t k = request.src0.ne[0]; + const uint64_t m = request.src0.ne[1]; + const uint64_t block_count = k / ::emel::kernel::detail::quant::QK_K; + std::array<::emel::kernel::detail::quant::block_q8_k, + ::emel::kernel::detail::quant::MAX_Q8_K_BLOCKS> + q8_blocks = {}; + ::emel::kernel::detail::quant::quantize_row_q8_k_strided( + static_cast(request.src1.data), 1u, q8_blocks.data(), + static_cast(k)); + + const uint8_t *a = static_cast(request.src0.data); + const size_t row_bytes = request.src0.nb[1]; + float *c = static_cast(request.dst.data); + + uint64_t row = 0u; + for (; row + 4u <= m; row += 4u) { + const auto *row0 = + reinterpret_cast( + a + (row + 0u) * row_bytes); + const auto *row1 = + reinterpret_cast( + a + (row + 1u) * row_bytes); + const auto *row2 = + reinterpret_cast( + a + (row + 2u) * row_bytes); + const auto *row3 = + reinterpret_cast( + a + (row + 3u) * row_bytes); + float out[4] = {}; + dot_q4_k_q8_k_4rows_neon(row0, row1, row2, row3, q8_blocks.data(), + block_count, out); + c[row + 0u] = out[0]; + c[row + 1u] = out[1]; + c[row + 2u] = out[2]; + c[row + 3u] = out[3]; + } + + for (; row + 2u <= m; row += 2u) { + const auto *row0 = + reinterpret_cast( + a + (row + 0u) * row_bytes); + const auto *row1 = + reinterpret_cast( + a + (row + 1u) * row_bytes); + float out[2] = {}; + dot_q4_k_q8_k_2rows_neon(row0, row1, q8_blocks.data(), block_count, out); + c[row + 0u] = out[0]; + c[row + 1u] = out[1]; + } + + for (; row < m; ++row) { + const auto *row_ptr = + reinterpret_cast( + a + row * row_bytes); + c[row] = dot_q4_k_q8_k_row_neon(row_ptr, q8_blocks.data(), block_count); + } +#endif +} + // Exact port of the pinned ggml_vec_dot_f16 aarch64 NEON fp16-arithmetic // path (GGML_F16_STEP=32): four float16x8_t accumulators advanced with // vfmaq_f16, pairwise vaddq_f16 reduce, f32 convert + horizontal add, and an @@ -6765,8 +6884,8 @@ inline float dot_f32_f32_row_neon(const int64_t count, const float *x, return 0.0f; #else const int64_t np = count & ~static_cast(15); - float32x4_t sum[4] = {vdupq_n_f32(0.0f), vdupq_n_f32(0.0f), - vdupq_n_f32(0.0f), vdupq_n_f32(0.0f)}; + float32x4_t sum[4] = {vdupq_n_f32(0.0f), vdupq_n_f32(0.0f), vdupq_n_f32(0.0f), + vdupq_n_f32(0.0f)}; for (int64_t i = 0; i < np; i += 16) { for (int64_t j = 0; j < 4; ++j) { const float32x4_t ax = vld1q_f32(x + i + j * 4); @@ -6785,15 +6904,10 @@ inline float dot_f32_f32_row_neon(const int64_t count, const float *x, #endif } -inline void dot_f32_f32_4rows_neon(const int64_t count, - const float *row0, - const float *row1, - const float *row2, - const float *row3, - const float *y, - float &out0, - float &out1, - float &out2, +inline void dot_f32_f32_4rows_neon(const int64_t count, const float *row0, + const float *row1, const float *row2, + const float *row3, const float *y, + float &out0, float &out1, float &out2, float &out3) noexcept { #if !(defined(__aarch64__) || defined(__ARM_NEON)) (void)count; @@ -6865,16 +6979,10 @@ inline void execute_neon_mul_mat_f32_vector_unchecked( float *dst = static_cast(request.dst.data); uint64_t row = 0u; for (; row + 4u <= m; row += 4u) { - dot_f32_f32_4rows_neon(static_cast(k), - a + (row + 0u) * k, - a + (row + 1u) * k, - a + (row + 2u) * k, - a + (row + 3u) * k, - y, - dst[row + 0u], - dst[row + 1u], - dst[row + 2u], - dst[row + 3u]); + dot_f32_f32_4rows_neon(static_cast(k), a + (row + 0u) * k, + a + (row + 1u) * k, a + (row + 2u) * k, + a + (row + 3u) * k, y, dst[row + 0u], dst[row + 1u], + dst[row + 2u], dst[row + 3u]); } for (; row < m; ++row) { dst[row] = dot_f32_f32_row_neon(static_cast(k), a + row * k, y); @@ -8498,6 +8606,19 @@ struct exec_simd_q4_vector_packed_q8_rhs_bl4_matrix_x4_op_mul_mat { } }; +struct exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat { + void operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, + context &ctx) const noexcept { + ::emel::kernel::aarch64::detail:: + execute_neon_mul_mat_q4_vector_packed_f32_rhs_bl4_unchecked( + ev.request); + ++ctx.optimized_q4_dispatch_count; + ++ctx.optimized_q4_vector_dispatch_count; + ++ctx.optimized_q4_vector_packed_dispatch_count; + detail::mark_done(ev, ctx); + } +}; + struct exec_simd_q4_vector_packed_q8_rhs_bl8_op_mul_mat { void operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, context &ctx) const noexcept { @@ -8511,6 +8632,19 @@ struct exec_simd_q4_vector_packed_q8_rhs_bl8_op_mul_mat { } }; +struct exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat { + void operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, + context &ctx) const noexcept { + ::emel::kernel::aarch64::detail:: + execute_neon_mul_mat_q4_vector_packed_f32_rhs_bl8_unchecked( + ev.request); + ++ctx.optimized_q4_dispatch_count; + ++ctx.optimized_q4_vector_dispatch_count; + ++ctx.optimized_q4_vector_packed_dispatch_count; + detail::mark_done(ev, ctx); + } +}; + struct exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x4_op_mul_mat { void operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, context &ctx) const noexcept { @@ -8550,6 +8684,17 @@ struct exec_simd_q4_vector_q8_rhs_op_mul_mat { } }; +struct exec_simd_q4_vector_f32_rhs_op_mul_mat { + void operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, + context &ctx) const noexcept { + ::emel::kernel::aarch64::detail:: + execute_neon_mul_mat_q4_vector_f32_rhs_unchecked(ev.request); + ++ctx.optimized_q4_dispatch_count; + ++ctx.optimized_q4_vector_dispatch_count; + detail::mark_done(ev, ctx); + } +}; + struct exec_simd_q8_0_vector_op_mul_mat { void operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, context &ctx) const noexcept { @@ -8828,6 +8973,34 @@ struct exec_simd_q6_vector_q8_argmax_prepared_i8mm_op_mul_mat_argmax { } }; +struct exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat_argmax { + void operator()( + const ::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax &ev, + context &ctx) const noexcept { + ::emel::kernel::aarch64::detail:: + execute_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4_unchecked( + ev.request); + ++ctx.optimized_q4_dispatch_count; + ++ctx.optimized_q4_vector_dispatch_count; + ++ctx.optimized_q4_vector_packed_dispatch_count; + detail::mark_done(ev, ctx); + } +}; + +struct exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat_argmax { + void operator()( + const ::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax &ev, + context &ctx) const noexcept { + ::emel::kernel::aarch64::detail:: + execute_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8_unchecked( + ev.request); + ++ctx.optimized_q4_dispatch_count; + ++ctx.optimized_q4_vector_dispatch_count; + ++ctx.optimized_q4_vector_packed_dispatch_count; + detail::mark_done(ev, ctx); + } +}; + struct exec_simd_q6_vector_packed_q8_rhs_op_mul_mat_argmax { void operator()( const ::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax &ev, @@ -8901,14 +9074,20 @@ using exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_t = detail::exec_simd_q4_vector_packed_q8_rhs_bl4_op_mul_mat; using exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4_t = detail::exec_simd_q4_vector_packed_q8_rhs_bl4_matrix_x4_op_mul_mat; +using exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4_t = + detail::exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat; using exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_t = detail::exec_simd_q4_vector_packed_q8_rhs_bl8_op_mul_mat; +using exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8_t = + detail::exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat; using exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8_t = detail::exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x8_op_mul_mat; using exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4_t = detail::exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x4_op_mul_mat; using exec_simd_op_mul_mat_q4_vector_q8_rhs_t = detail::exec_simd_q4_vector_q8_rhs_op_mul_mat; +using exec_simd_op_mul_mat_q4_vector_f32_rhs_t = + detail::exec_simd_q4_vector_f32_rhs_op_mul_mat; using exec_simd_op_mul_mat_q5_0_vector_t = detail::exec_simd_q5_0_vector_op_mul_mat; using exec_simd_op_mul_mat_q4_0_vector_t = @@ -8947,6 +9126,10 @@ using exec_simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_t = detail::exec_simd_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_op_mul_mat; using exec_simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs_t = detail::exec_simd_q6_vector_packed_q8_rhs_op_mul_mat_argmax; +using exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4_t = + detail::exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat_argmax; +using exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8_t = + detail::exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat_argmax; using exec_simd_op_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm_t = detail::exec_simd_q6_vector_prepared_q8_rhs_i8mm_op_mul_mat_argmax; using exec_simd_op_mul_mat_argmax_q6_vector_q8_argmax_prepared_i8mm_t = @@ -9079,14 +9262,20 @@ inline constexpr exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_t exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4{}; inline constexpr exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4_t exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4{}; +inline constexpr exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4_t + exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4{}; inline constexpr exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_t exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8{}; +inline constexpr exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8_t + exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8{}; inline constexpr exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8_t exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8{}; inline constexpr exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4_t exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4{}; inline constexpr exec_simd_op_mul_mat_q4_vector_q8_rhs_t exec_simd_op_mul_mat_q4_vector_q8_rhs{}; +inline constexpr exec_simd_op_mul_mat_q4_vector_f32_rhs_t + exec_simd_op_mul_mat_q4_vector_f32_rhs{}; inline constexpr exec_simd_op_mul_mat_q5_0_vector_t exec_simd_op_mul_mat_q5_0_vector{}; inline constexpr exec_simd_op_mul_mat_q4_0_vector_t @@ -9125,6 +9314,10 @@ inline constexpr exec_simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_t exec_simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4{}; inline constexpr exec_simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs_t exec_simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs{}; +inline constexpr exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4_t + exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4{}; +inline constexpr exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8_t + exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8{}; inline constexpr exec_simd_op_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm_t exec_simd_op_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm{}; inline constexpr exec_simd_op_mul_mat_argmax_q6_vector_q8_argmax_prepared_i8mm_t diff --git a/src/emel/kernel/aarch64/guards.hpp b/src/emel/kernel/aarch64/guards.hpp index 29191671..5f98e915 100644 --- a/src/emel/kernel/aarch64/guards.hpp +++ b/src/emel/kernel/aarch64/guards.hpp @@ -18,9 +18,9 @@ namespace detail { // rows) and the group-aligned row-slice lane view emitted by the parallel // matmul slicer, whose slice is embedded in a wider output (nb[0] covers the // full output row while ne[1]/nb[2] describe only the slice rows). -inline bool is_batch_major_dst_view(const ::emel::kernel::event::tensor_view_mut &dst, - const uint64_t m, - const uint64_t rhs_rows) noexcept { +inline bool +is_batch_major_dst_view(const ::emel::kernel::event::tensor_view_mut &dst, + const uint64_t m, const uint64_t rhs_rows) noexcept { // Keep every byte-stride term in uint64_t: mixing size_t in the products // could truncate on 32-bit hosts and mis-accept a stride contract. constexpr uint64_t k_f32_bytes = sizeof(float); @@ -33,7 +33,8 @@ inline bool is_batch_major_dst_view(const ::emel::kernel::event::tensor_view_mut } inline bool can_use_neon_mul_mat_q8_0_packed_bl8_matrix_x4( - const ::emel::kernel::event::op_mul_mat &request, const bool neon_available) noexcept { + const ::emel::kernel::event::op_mul_mat &request, + const bool neon_available) noexcept { const uint64_t k = request.src0.ne[0]; const uint64_t m = request.src0.ne[1]; const uint64_t rhs_rows = request.src1.ne[0]; @@ -43,8 +44,10 @@ inline bool can_use_neon_mul_mat_q8_0_packed_bl8_matrix_x4( ::emel::kernel::detail::quant::packed_q8_0_x4_group_count(rhs_rows); const size_t group_bytes = ::emel::kernel::detail::quant::packed_q8_0_x4_group_storage_bytes(k); - return neon_available && ::emel::kernel::aarch64::detail::neon_q8_0_packed_bl8_supported() && k != 0u && - m != 0u && rhs_rows == ::emel::kernel::detail::quant::Q8_0_X4_ROWS && + return neon_available && + ::emel::kernel::aarch64::detail::neon_q8_0_packed_bl8_supported() && + k != 0u && m != 0u && + rhs_rows == ::emel::kernel::detail::quant::Q8_0_X4_ROWS && request.src1.ne[1] == k && request.dst.ne[0] == rhs_rows && request.dst.ne[1] == m && request.src0.ne[2] == 1u && request.src0.ne[3] == 1u && request.src1.ne[2] == 1u && @@ -68,7 +71,8 @@ inline bool can_use_neon_mul_mat_q8_0_packed_bl8_matrix_x4( } inline bool can_run_neon_mul_mat_q4_vector_packed_q8_rhs_matrix_x4_request( - const ::emel::kernel::event::op_mul_mat &request, const uint8_t packed_dtype) noexcept { + const ::emel::kernel::event::op_mul_mat &request, + const uint8_t packed_dtype) noexcept { const uint64_t k = request.src0.ne[0]; const uint64_t m = request.src0.ne[1]; const uint64_t rhs_rows = request.src1.ne[0]; @@ -103,8 +107,8 @@ inline bool can_run_neon_mul_mat_q4_vector_packed_q8_rhs_matrix_x4_request( } inline bool can_run_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4_request( - const ::emel::kernel::event::op_mul_mat &request, const uint8_t packed_dtype, - const size_t group_bytes) noexcept { + const ::emel::kernel::event::op_mul_mat &request, + const uint8_t packed_dtype, const size_t group_bytes) noexcept { const uint64_t k = request.src0.ne[0]; const uint64_t m = request.src0.ne[1]; const uint64_t rhs_rows = request.src1.ne[0]; @@ -137,22 +141,28 @@ inline bool can_run_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4_request( } inline bool can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4( - const ::emel::kernel::event::op_mul_mat &request, const bool neon_available) noexcept { - return neon_available && ::emel::kernel::aarch64::detail::neon_q4_vector_packed_supported() && + const ::emel::kernel::event::op_mul_mat &request, + const bool neon_available) noexcept { + return neon_available && + ::emel::kernel::aarch64::detail::neon_q4_vector_packed_supported() && can_run_neon_mul_mat_q4_vector_packed_q8_rhs_matrix_x4_request( request, ::emel::kernel::detail::dtype_q4_k_x8_bl4); } inline bool can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4( - const ::emel::kernel::event::op_mul_mat &request, const bool neon_available) noexcept { - return neon_available && ::emel::kernel::aarch64::detail::neon_q4_vector_packed_supported() && + const ::emel::kernel::event::op_mul_mat &request, + const bool neon_available) noexcept { + return neon_available && + ::emel::kernel::aarch64::detail::neon_q4_vector_packed_supported() && can_run_neon_mul_mat_q4_vector_packed_q8_rhs_matrix_x4_request( request, ::emel::kernel::detail::dtype_q4_k_x8_bl8); } inline bool can_use_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4( - const ::emel::kernel::event::op_mul_mat &request, const bool neon_available) noexcept { - return neon_available && ::emel::kernel::aarch64::detail::neon_q6_vector_packed_supported() && + const ::emel::kernel::event::op_mul_mat &request, + const bool neon_available) noexcept { + return neon_available && + ::emel::kernel::aarch64::detail::neon_q6_vector_packed_supported() && can_run_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4_request( request, ::emel::kernel::detail::dtype_q6_k_x8, ::emel::kernel::detail::quant::packed_q6_k_x8_group_storage_bytes( @@ -160,15 +170,17 @@ inline bool can_use_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4( } inline bool can_use_neon_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4( - const ::emel::kernel::event::op_mul_mat &request, const bool neon_available) noexcept { - return neon_available && ::emel::kernel::aarch64::detail::neon_q6_vector_prepared_q8_rhs_i8mm_supported() && + const ::emel::kernel::event::op_mul_mat &request, + const bool neon_available) noexcept { + return neon_available && + ::emel::kernel::aarch64::detail:: + neon_q6_vector_prepared_q8_rhs_i8mm_supported() && can_run_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4_request( request, ::emel::kernel::detail::dtype_q6_k_x8_q8_prepared, ::emel::kernel::detail::quant:: prepared_q6_k_x8_q8_group_storage_bytes(request.src0.ne[0])); } - inline bool can_run_neon_mul_mat_q4_vector_packed_q8_rhs_matrix_x8_request( const ::emel::kernel::event::op_mul_mat &request, const uint8_t packed_dtype) noexcept { @@ -182,34 +194,27 @@ inline bool can_run_neon_mul_mat_q4_vector_packed_q8_rhs_matrix_x8_request( const size_t rhs_row_bytes = ::emel::kernel::detail::quantized_row_storage_bytes( ::emel::kernel::detail::dtype_q8_k, k); - return k != 0u && - m != 0u && - rhs_rows == ::emel::kernel::detail::quant::Q4_K_X8_ROWS && - request.src1.ne[1] == k && - request.dst.ne[0] == rhs_rows && - request.dst.ne[1] == m && - request.src0.ne[2] == 1u && - request.src0.ne[3] == 1u && - request.src1.ne[2] == 1u && - request.src1.ne[3] == 1u && - request.dst.ne[2] == 1u && - request.dst.ne[3] == 1u && - ::emel::kernel::detail::dtype_code(request.src0.type) == packed_dtype && - ::emel::kernel::detail::dtype_code(request.src1.type) == - ::emel::kernel::detail::dtype_q8_k_x8 && - ::emel::kernel::detail::dtype_code(request.dst.type) == - ::emel::kernel::detail::dtype_f32 && - request.src0.nb[0] == 1u && - group_bytes != 0u && - request.src0.nb[1] == group_bytes && - request.src0.nb[2] == group_bytes * group_count && - request.src0.nb[3] == request.src0.nb[2] && - request.src1.nb[0] == 1u && - rhs_row_bytes != 0u && - request.src1.nb[1] == rhs_row_bytes && - request.src1.nb[2] == rhs_row_bytes * rhs_rows && - request.src1.nb[3] == request.src1.nb[2] && - is_batch_major_dst_view(request.dst, m, rhs_rows); + return k != 0u && m != 0u && + rhs_rows == ::emel::kernel::detail::quant::Q4_K_X8_ROWS && + request.src1.ne[1] == k && request.dst.ne[0] == rhs_rows && + request.dst.ne[1] == m && request.src0.ne[2] == 1u && + request.src0.ne[3] == 1u && request.src1.ne[2] == 1u && + request.src1.ne[3] == 1u && request.dst.ne[2] == 1u && + request.dst.ne[3] == 1u && + ::emel::kernel::detail::dtype_code(request.src0.type) == + packed_dtype && + ::emel::kernel::detail::dtype_code(request.src1.type) == + ::emel::kernel::detail::dtype_q8_k_x8 && + ::emel::kernel::detail::dtype_code(request.dst.type) == + ::emel::kernel::detail::dtype_f32 && + request.src0.nb[0] == 1u && group_bytes != 0u && + request.src0.nb[1] == group_bytes && + request.src0.nb[2] == group_bytes * group_count && + request.src0.nb[3] == request.src0.nb[2] && request.src1.nb[0] == 1u && + rhs_row_bytes != 0u && request.src1.nb[1] == rhs_row_bytes && + request.src1.nb[2] == rhs_row_bytes * rhs_rows && + request.src1.nb[3] == request.src1.nb[2] && + is_batch_major_dst_view(request.dst, m, rhs_rows); } inline bool @@ -225,35 +230,27 @@ can_run_neon_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x8_request( const size_t rhs_row_bytes = ::emel::kernel::detail::quantized_row_storage_bytes( ::emel::kernel::detail::dtype_q8_k, k); - return k != 0u && - m != 0u && - rhs_rows == ::emel::kernel::detail::quant::Q6_K_X8_ROWS && - request.src1.ne[1] == k && - request.dst.ne[0] == rhs_rows && - request.dst.ne[1] == m && - request.src0.ne[2] == 1u && - request.src0.ne[3] == 1u && - request.src1.ne[2] == 1u && - request.src1.ne[3] == 1u && - request.dst.ne[2] == 1u && - request.dst.ne[3] == 1u && - ::emel::kernel::detail::dtype_code(request.src0.type) == - ::emel::kernel::detail::dtype_q6_k_x8_q8_prepared && - ::emel::kernel::detail::dtype_code(request.src1.type) == - ::emel::kernel::detail::dtype_q8_k_x8 && - ::emel::kernel::detail::dtype_code(request.dst.type) == - ::emel::kernel::detail::dtype_f32 && - request.src0.nb[0] == 1u && - group_bytes != 0u && - request.src0.nb[1] == group_bytes && - request.src0.nb[2] == group_bytes * group_count && - request.src0.nb[3] == request.src0.nb[2] && - request.src1.nb[0] == 1u && - rhs_row_bytes != 0u && - request.src1.nb[1] == rhs_row_bytes && - request.src1.nb[2] == rhs_row_bytes * rhs_rows && - request.src1.nb[3] == request.src1.nb[2] && - is_batch_major_dst_view(request.dst, m, rhs_rows); + return k != 0u && m != 0u && + rhs_rows == ::emel::kernel::detail::quant::Q6_K_X8_ROWS && + request.src1.ne[1] == k && request.dst.ne[0] == rhs_rows && + request.dst.ne[1] == m && request.src0.ne[2] == 1u && + request.src0.ne[3] == 1u && request.src1.ne[2] == 1u && + request.src1.ne[3] == 1u && request.dst.ne[2] == 1u && + request.dst.ne[3] == 1u && + ::emel::kernel::detail::dtype_code(request.src0.type) == + ::emel::kernel::detail::dtype_q6_k_x8_q8_prepared && + ::emel::kernel::detail::dtype_code(request.src1.type) == + ::emel::kernel::detail::dtype_q8_k_x8 && + ::emel::kernel::detail::dtype_code(request.dst.type) == + ::emel::kernel::detail::dtype_f32 && + request.src0.nb[0] == 1u && group_bytes != 0u && + request.src0.nb[1] == group_bytes && + request.src0.nb[2] == group_bytes * group_count && + request.src0.nb[3] == request.src0.nb[2] && request.src1.nb[0] == 1u && + rhs_row_bytes != 0u && request.src1.nb[1] == rhs_row_bytes && + request.src1.nb[2] == rhs_row_bytes * rhs_rows && + request.src1.nb[3] == request.src1.nb[2] && + is_batch_major_dst_view(request.dst, m, rhs_rows); } inline bool can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8( @@ -454,8 +451,7 @@ struct simd_op_mul_mat_q8_0_vector_q8_rhs { return false; } return ::emel::kernel::aarch64::detail:: - can_use_neon_mul_mat_q8_0_vector_q8_rhs(ev.request, - ctx.neon_available); + can_use_neon_mul_mat_q8_0_vector_q8_rhs(ev.request, ctx.neon_available); } }; @@ -477,9 +473,20 @@ struct simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4 { if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { return false; } - return detail:: - can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4( - ev.request, ctx.neon_available); + return detail::can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4( + ev.request, ctx.neon_available); + } +}; + +struct simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4 { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, + const action::context &ctx) const noexcept { + if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { + return false; + } + return ::emel::kernel::aarch64::detail:: + can_use_neon_mul_mat_q4_vector_packed_f32_rhs_bl4(ev.request, + ctx.neon_available); } }; @@ -495,15 +502,26 @@ struct simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8 { } }; +struct simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8 { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, + const action::context &ctx) const noexcept { + if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { + return false; + } + return ::emel::kernel::aarch64::detail:: + can_use_neon_mul_mat_q4_vector_packed_f32_rhs_bl8(ev.request, + ctx.neon_available); + } +}; + struct simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4 { bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, const action::context &ctx) const noexcept { if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { return false; } - return detail:: - can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4( - ev.request, ctx.neon_available); + return detail::can_use_neon_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4( + ev.request, ctx.neon_available); } }; @@ -525,8 +543,18 @@ struct simd_op_mul_mat_q4_vector_q8_rhs { return false; } return ::emel::kernel::aarch64::detail:: - can_use_neon_mul_mat_q4_vector_q8_rhs(ev.request, - ctx.neon_available); + can_use_neon_mul_mat_q4_vector_q8_rhs(ev.request, ctx.neon_available); + } +}; + +struct simd_op_mul_mat_q4_vector_f32_rhs { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_mul_mat &ev, + const action::context &ctx) const noexcept { + if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { + return false; + } + return ::emel::kernel::aarch64::detail:: + can_use_neon_mul_mat_q4_vector_f32_rhs(ev.request, ctx.neon_available); } }; @@ -548,8 +576,7 @@ struct simd_op_mul_mat_q6_vector_q8_rhs { return false; } return ::emel::kernel::aarch64::detail:: - can_use_neon_mul_mat_q6_vector_q8_rhs(ev.request, - ctx.neon_available); + can_use_neon_mul_mat_q6_vector_q8_rhs(ev.request, ctx.neon_available); } }; @@ -571,9 +598,8 @@ struct simd_op_mul_mat_q6_vector_packed_q8_rhs_matrix_x4 { if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { return false; } - return detail:: - can_use_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4( - ev.request, ctx.neon_available); + return detail::can_use_neon_mul_mat_q6_vector_packed_q8_rhs_matrix_x4( + ev.request, ctx.neon_available); } }; @@ -638,6 +664,32 @@ struct simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs { } }; +struct simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4 { + bool operator()( + const ::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax &ev, + const action::context &ctx) const noexcept { + if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { + return false; + } + return ::emel::kernel::aarch64::detail:: + can_use_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4( + ev.request, ctx.neon_available); + } +}; + +struct simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8 { + bool operator()( + const ::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax &ev, + const action::context &ctx) const noexcept { + if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { + return false; + } + return ::emel::kernel::aarch64::detail:: + can_use_neon_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8( + ev.request, ctx.neon_available); + } +}; + struct simd_op_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm { bool operator()( const ::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax &ev, @@ -682,9 +734,12 @@ struct simd_op_mul_mat_generic { !simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8{}(ev, ctx) && !simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4{}(ev, ctx) && !simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8{}(ev, ctx) && + !simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8{}(ev, ctx) && !simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4{}(ev, ctx) && !simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4{}(ev, ctx) && + !simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4{}(ev, ctx) && !simd_op_mul_mat_q4_vector_q8_rhs{}(ev, ctx) && + !simd_op_mul_mat_q4_vector_f32_rhs{}(ev, ctx) && !simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x8{}(ev, ctx) && !simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4{}(ev, diff --git a/src/emel/kernel/aarch64/sm.hpp b/src/emel/kernel/aarch64/sm.hpp index c6875f9f..8089a516 100644 --- a/src/emel/kernel/aarch64/sm.hpp +++ b/src/emel/kernel/aarch64/sm.hpp @@ -412,6 +412,11 @@ struct model { [ guard::simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8{} ] / action::exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8 + , sml::state <= sml::state + + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat> + [ guard::simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8{} ] + / action::exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8 + , sml::state <= sml::state + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat> [ guard::simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4{} ] @@ -422,11 +427,21 @@ struct model { [ guard::simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4{} ] / action::exec_simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4 + , sml::state <= sml::state + + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat> + [ guard::simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4{} ] + / action::exec_simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4 + , sml::state <= sml::state + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat> [ guard::simd_op_mul_mat_q4_vector_q8_rhs{} ] / action::exec_simd_op_mul_mat_q4_vector_q8_rhs + , sml::state <= sml::state + + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat> + [ guard::simd_op_mul_mat_q4_vector_f32_rhs{} ] + / action::exec_simd_op_mul_mat_q4_vector_f32_rhs + , sml::state <= sml::state + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat> [ guard::simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x8{} ] @@ -447,6 +462,16 @@ struct model { [ guard::simd_op_mul_mat_argmax_q6_vector_q8_argmax_prepared_i8mm{} ] / action::exec_simd_op_mul_mat_argmax_q6_vector_q8_argmax_prepared_i8mm + , sml::state <= sml::state + + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax> + [ guard::simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8{} ] + / action::exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8 + + , sml::state <= sml::state + + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax> + [ guard::simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4{} ] + / action::exec_simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4 + , sml::state <= sml::state + sml::event<::emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax> [ guard::simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs{} ] @@ -1290,7 +1315,7 @@ struct sm : public emel::sm { using base_type = emel::sm; using base_type::base_type; - bool process_event(const ::emel::kernel::event::dispatch & ev) { + bool process_event(const ::emel::kernel::event::dispatch &ev) { event::dispatch_ctx ctx{}; const event::dispatch_request dispatch{ev, ctx}; return process_dispatch_event(dispatch); @@ -1298,7 +1323,7 @@ struct sm : public emel::sm { template requires(::emel::kernel::is_op_event_v) - bool process_event(const event_type & ev) { + bool process_event(const event_type &ev) { event::dispatch_ctx ctx{}; using dispatch_event_type = event::dispatch_event_for_t; const dispatch_event_type dispatch{ev, ctx}; @@ -1365,7 +1390,8 @@ struct sm : public emel::sm { return this->context_.optimized_q8_0_packed_bl8_dispatch_count; } - uint64_t optimized_q8_0_packed_bl8_full_groups_dispatch_count() const noexcept { + uint64_t + optimized_q8_0_packed_bl8_full_groups_dispatch_count() const noexcept { return this->context_.optimized_q8_0_packed_bl8_full_groups_dispatch_count; } @@ -1437,24 +1463,32 @@ struct sm : public emel::sm { return this->context_.optimized_q6_vector_packed_q8_rhs_dispatch_count; } - uint64_t optimized_q6_vector_packed_q8_rhs_argmax_dispatch_count() const noexcept { - return this->context_.optimized_q6_vector_packed_q8_rhs_argmax_dispatch_count; + uint64_t + optimized_q6_vector_packed_q8_rhs_argmax_dispatch_count() const noexcept { + return this->context_ + .optimized_q6_vector_packed_q8_rhs_argmax_dispatch_count; } uint64_t optimized_q6_vector_prepared_q8_rhs_dispatch_count() const noexcept { return this->context_.optimized_q6_vector_prepared_q8_rhs_dispatch_count; } - uint64_t optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count() const noexcept { - return this->context_.optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count; + uint64_t + optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count() const noexcept { + return this->context_ + .optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count; } - uint64_t optimized_q6_vector_prepared_q8_rhs_argmax_i8mm_dispatch_count() const noexcept { - return this->context_.optimized_q6_vector_prepared_q8_rhs_argmax_i8mm_dispatch_count; + uint64_t optimized_q6_vector_prepared_q8_rhs_argmax_i8mm_dispatch_count() + const noexcept { + return this->context_ + .optimized_q6_vector_prepared_q8_rhs_argmax_i8mm_dispatch_count; } - uint64_t optimized_q6_vector_q8_argmax_prepared_i8mm_dispatch_count() const noexcept { - return this->context_.optimized_q6_vector_q8_argmax_prepared_i8mm_dispatch_count; + uint64_t + optimized_q6_vector_q8_argmax_prepared_i8mm_dispatch_count() const noexcept { + return this->context_ + .optimized_q6_vector_q8_argmax_prepared_i8mm_dispatch_count; } uint64_t shared_q6_dispatch_count() const noexcept { @@ -1465,12 +1499,13 @@ struct sm : public emel::sm { return this->context_.shared_flash_dispatch_count; } - private: +private: template - bool process_dispatch_event(const dispatch_event_type & ev) { + bool process_dispatch_event(const dispatch_event_type &ev) { const bool accepted = base_type::process_event(ev); - return accepted && ev.ctx.err == static_cast(emel::error::cast(error::none)); + return accepted && + ev.ctx.err == static_cast(emel::error::cast(error::none)); } }; -} // namespace emel::kernel::aarch64 +} // namespace emel::kernel::aarch64 diff --git a/src/emel/kernel/any.hpp b/src/emel/kernel/any.hpp index a62ccbb1..a85d0942 100644 --- a/src/emel/kernel/any.hpp +++ b/src/emel/kernel/any.hpp @@ -27,7 +27,7 @@ constexpr kernel_kind detect_host_kind() noexcept { class any { public: - any() = default; + any() : core_(detect_host_kind()) {} explicit any(const kernel_kind kind) : core_(kind) {} any(const any &) = delete; diff --git a/src/emel/kernel/detail.hpp b/src/emel/kernel/detail.hpp index c7f48aba..a6238bbe 100644 --- a/src/emel/kernel/detail.hpp +++ b/src/emel/kernel/detail.hpp @@ -272,7 +272,7 @@ struct block_q6_k { struct block_q4_kx8 { std::array d = {}; std::array dmin = {}; - std::array scales = {}; + std::array scales = {}; std::array qs = {}; }; @@ -319,7 +319,7 @@ static_assert(sizeof(block_q5_k) == static_assert(sizeof(block_q6_k) == sizeof(uint16_t) + (QK_K / 16) + (3 * QK_K / 4)); static_assert(sizeof(block_q4_kx8) == sizeof(uint16_t) * (Q4_K_X8_ROWS * 2u) + - ((QK_K / 32u) * Q4_K_X8_ROWS * 2u) + + K_SCALE_SIZE * Q4_K_X8_ROWS + (QK_K / 2) * Q4_K_X8_ROWS); static_assert(sizeof(block_q6_kx8) == sizeof(uint16_t) * Q6_K_X8_ROWS + (QK_K / 16) * Q6_K_X8_ROWS + @@ -949,19 +949,75 @@ make_block_q4_k_x8(const block_q4_k *rows, static_cast(interleave_block_bytes)); } - for (uint64_t sb = 0; sb < (QK_K / 64u); ++sb) { - for (uint64_t half = 0; half < 2u; ++half) { - const uint64_t scale_index = sb * 2u + half; - uint8_t *packed = out.scales.data() + (scale_index * Q4_K_X8_ROWS * 2u); - for (uint64_t row = 0; row < Q4_K_X8_ROWS; ++row) { - uint8_t scale = 0u; - uint8_t min = 0u; - get_scale_min_k4(static_cast(scale_index), rows[row].scales.data(), - &scale, &min); - packed[row] = min; - packed[row + Q4_K_X8_ROWS] = scale; - } - } + std::array scales = {}; + std::array mins = {}; + for (uint64_t i = 0; i < 4u; ++i) { + for (uint64_t row = 0; row < Q4_K_X8_ROWS; ++row) { + scales[row] = rows[row].scales[i] & 63u; + mins[row] = rows[row].scales[i + 4u] & 63u; + } + + out.scales[i * 12u + 0u] = + static_cast((scales[0] & 63u) + ((scales[4] & 48u) << 2u)); + out.scales[i * 12u + 1u] = + static_cast((scales[1] & 63u) + ((scales[5] & 48u) << 2u)); + out.scales[i * 12u + 2u] = + static_cast((scales[2] & 63u) + ((scales[6] & 48u) << 2u)); + out.scales[i * 12u + 3u] = + static_cast((scales[3] & 63u) + ((scales[7] & 48u) << 2u)); + out.scales[i * 12u + 4u] = + static_cast((mins[0] & 63u) + ((mins[4] & 48u) << 2u)); + out.scales[i * 12u + 5u] = + static_cast((mins[1] & 63u) + ((mins[5] & 48u) << 2u)); + out.scales[i * 12u + 6u] = + static_cast((mins[2] & 63u) + ((mins[6] & 48u) << 2u)); + out.scales[i * 12u + 7u] = + static_cast((mins[3] & 63u) + ((mins[7] & 48u) << 2u)); + out.scales[i * 12u + 8u] = + static_cast((scales[4] & 15u) + ((mins[4] & 15u) << 4u)); + out.scales[i * 12u + 9u] = + static_cast((scales[5] & 15u) + ((mins[5] & 15u) << 4u)); + out.scales[i * 12u + 10u] = + static_cast((scales[6] & 15u) + ((mins[6] & 15u) << 4u)); + out.scales[i * 12u + 11u] = + static_cast((scales[7] & 15u) + ((mins[7] & 15u) << 4u)); + } + + for (uint64_t i = 0; i < 4u; ++i) { + for (uint64_t row = 0; row < Q4_K_X8_ROWS; ++row) { + scales[row] = static_cast( + ((rows[row].scales[i] & 192u) >> 2u) | + (rows[row].scales[i + 8u] & 15u)); + mins[row] = static_cast( + ((rows[row].scales[i + 4u] & 192u) >> 2u) | + ((rows[row].scales[i + 8u] & 240u) >> 4u)); + } + + const uint64_t base = i * 12u + 48u; + out.scales[base + 0u] = + static_cast((scales[0] & 63u) + ((scales[4] & 48u) << 2u)); + out.scales[base + 1u] = + static_cast((scales[1] & 63u) + ((scales[5] & 48u) << 2u)); + out.scales[base + 2u] = + static_cast((scales[2] & 63u) + ((scales[6] & 48u) << 2u)); + out.scales[base + 3u] = + static_cast((scales[3] & 63u) + ((scales[7] & 48u) << 2u)); + out.scales[base + 4u] = + static_cast((mins[0] & 63u) + ((mins[4] & 48u) << 2u)); + out.scales[base + 5u] = + static_cast((mins[1] & 63u) + ((mins[5] & 48u) << 2u)); + out.scales[base + 6u] = + static_cast((mins[2] & 63u) + ((mins[6] & 48u) << 2u)); + out.scales[base + 7u] = + static_cast((mins[3] & 63u) + ((mins[7] & 48u) << 2u)); + out.scales[base + 8u] = + static_cast((scales[4] & 15u) + ((mins[4] & 15u) << 4u)); + out.scales[base + 9u] = + static_cast((scales[5] & 15u) + ((mins[5] & 15u) << 4u)); + out.scales[base + 10u] = + static_cast((scales[6] & 15u) + ((mins[6] & 15u) << 4u)); + out.scales[base + 11u] = + static_cast((scales[7] & 15u) + ((mins[7] & 15u) << 4u)); } return out; @@ -2780,21 +2836,109 @@ inline float dot_q4_k_q8_k_block_scalar(const quant::block_q4_k &lhs, const float d = quant::fp16_to_fp32(lhs.d) * rhs.d; const float dmin = quant::fp16_to_fp32(lhs.dmin) * rhs.d; - float sum = -dmin * static_cast(min_sum); - for (int32_t lane : aux32) { - sum += d * static_cast(lane); + float sumf = -dmin * static_cast(min_sum); + for (const int32_t lane : aux32) { + sumf += d * static_cast(lane); } - return sum; + return sumf; } inline float dot_q4_k_q8_k_row_scalar(const quant::block_q4_k *lhs, const quant::block_q8_k *rhs, const uint64_t block_count) noexcept { - float sum = 0.0f; + constexpr uint32_t kmask1 = 0x3f3f3f3fu; + constexpr uint32_t kmask2 = 0x0f0f0f0fu; + constexpr uint32_t kmask3 = 0x03030303u; + + alignas(64) int8_t aux8[quant::QK_K] = {}; + int16_t aux16[8] = {}; + int32_t aux32[8] = {}; + uint32_t auxs[4] = {}; + float sums[8] = {}; + + const uint8_t *scales = reinterpret_cast(auxs); + const uint8_t *mins = reinterpret_cast(auxs + 2); + + float sumf = 0.0f; for (uint64_t block = 0; block < block_count; ++block) { - sum += dot_q4_k_q8_k_block_scalar(lhs[block], rhs[block]); + const uint8_t *q4 = lhs[block].qs.data(); + const int8_t *q8 = rhs[block].qs.data(); + int8_t *a = aux8; + for (uint64_t group = 0; group < (quant::QK_K / 64u); ++group) { + for (uint64_t lane = 0; lane < 32u; ++lane) { + a[lane] = static_cast(q4[lane] & 0x0fu); + } + a += 32; + for (uint64_t lane = 0; lane < 32u; ++lane) { + a[lane] = static_cast(q4[lane] >> 4u); + } + a += 32; + q4 += 32; + } + + std::memcpy(auxs, lhs[block].scales.data(), lhs[block].scales.size()); + auxs[3] = ((auxs[2] >> 4u) & kmask2) | (((auxs[1] >> 6u) & kmask3) << 4u); + const uint32_t aux = auxs[1] & kmask1; + auxs[1] = (auxs[2] & kmask2) | (((auxs[0] >> 6u) & kmask3) << 4u); + auxs[2] = aux; + auxs[0] &= kmask1; + + int32_t min_sum = 0; + for (uint64_t group = 0; group < (quant::QK_K / 16u); ++group) { + min_sum += static_cast(rhs[block].bsums[group]) * + static_cast(mins[group / 2u]); + } + + std::memset(aux32, 0, sizeof(aux32)); + a = aux8; + int scale_index = 0; + for (uint64_t group = 0; group < (quant::QK_K / 32u); ++group) { + const int32_t scale = scales[scale_index++]; + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux16[lane] = static_cast(q8[lane] * a[lane]); + } + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux32[lane] += scale * static_cast(aux16[lane]); + } + q8 += 8; + a += 8; + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux16[lane] = static_cast(q8[lane] * a[lane]); + } + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux32[lane] += scale * static_cast(aux16[lane]); + } + q8 += 8; + a += 8; + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux16[lane] = static_cast(q8[lane] * a[lane]); + } + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux32[lane] += scale * static_cast(aux16[lane]); + } + q8 += 8; + a += 8; + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux16[lane] = static_cast(q8[lane] * a[lane]); + } + for (uint64_t lane = 0; lane < 8u; ++lane) { + aux32[lane] += scale * static_cast(aux16[lane]); + } + q8 += 8; + a += 8; + } + + const float d = quant::fp16_to_fp32(lhs[block].d) * rhs[block].d; + for (int lane = 0; lane < 8; ++lane) { + sums[lane] += d * static_cast(aux32[lane]); + } + const float dmin = quant::fp16_to_fp32(lhs[block].dmin) * rhs[block].d; + sumf -= dmin * static_cast(min_sum); } - return sum; + for (const float lane : sums) { + sumf += lane; + } + return sumf; } inline float dot_q5_k_q8_k_block_scalar(const quant::block_q5_k &lhs, @@ -3933,10 +4077,48 @@ inline __m256 v_expf_ggml(__m256 x) noexcept { } #endif +#if defined(__aarch64__) && defined(__ARM_NEON) +// Exact port of ggml_v_expf's AArch64 NEON polynomial. +inline float32x4_t v_expf_ggml(float32x4_t x) noexcept { + const float32x4_t r = vdupq_n_f32(0x1.8p23f); + const float32x4_t z = vfmaq_f32(r, x, vdupq_n_f32(0x1.715476p+0f)); + const float32x4_t n = vsubq_f32(z, r); + const float32x4_t b = + vfmsq_f32(vfmsq_f32(x, n, vdupq_n_f32(0x1.62e4p-1f)), n, + vdupq_n_f32(0x1.7f7d1cp-20f)); + const uint32x4_t e = vshlq_n_u32(vreinterpretq_u32_f32(z), 23); + const float32x4_t k = vreinterpretq_f32_u32( + vaddq_u32(e, vreinterpretq_u32_f32(vdupq_n_f32(1.0f)))); + const uint32x4_t c = vcagtq_f32(n, vdupq_n_f32(126.0f)); + const float32x4_t u = vmulq_f32(b, b); + const float32x4_t j = vfmaq_f32( + vmulq_f32(vdupq_n_f32(0x1.ffffecp-1f), b), + vfmaq_f32( + vfmaq_f32(vdupq_n_f32(0x1.fffdb6p-2f), + vdupq_n_f32(0x1.555e66p-3f), b), + vfmaq_f32(vdupq_n_f32(0x1.573e2ep-5f), + vdupq_n_f32(0x1.0e4020p-7f), b), + u), + u); + if (vpaddd_u64(vreinterpretq_u64_u32(c)) == 0u) { + return vfmaq_f32(k, k, j); + } + const uint32x4_t d = + vandq_u32(vclezq_f32(n), vdupq_n_u32(0x82000000u)); + const float32x4_t s1 = + vreinterpretq_f32_u32(vaddq_u32(d, vdupq_n_u32(0x7f000000u))); + const float32x4_t s2 = vreinterpretq_f32_u32(vsubq_u32(e, d)); + return vbslq_f32( + vcagtq_f32(n, vdupq_n_f32(192.0f)), vmulq_f32(s1, s1), + vbslq_f32(c, vmulq_f32(vfmaq_f32(s2, s2, j), s1), + vfmaq_f32(k, k, j))); +} +#endif + // Exact port of ggml's soft_max row kernel over a pre-scaled, pre-masked -// row: max (order independent), 8-lane v_expf blocks with per-block -// horizontal reduce into a double sum, libm expf scalar tail, then a -// per-element multiply by (float)(1.0 / sum). +// row: max (order independent), architecture-native v_expf blocks with +// per-block horizontal reduction into a double sum, libm expf scalar tail, +// then a per-element multiply by (float)(1.0 / sum). inline void soft_max_row_ggml(const int64_t count, float *data) noexcept { float max_value = -std::numeric_limits::infinity(); for (int64_t i = 0; i < count; ++i) { @@ -3955,6 +4137,13 @@ inline void soft_max_row_ggml(const int64_t count, float *data) noexcept { val2 = _mm_add_ss(val2, _mm_movehdup_ps(val2)); sum += static_cast(_mm_cvtss_f32(val2)); } +#elif defined(__aarch64__) && defined(__ARM_NEON) + for (; i + 3 < count; i += 4) { + const float32x4_t val = v_expf_ggml( + vsubq_f32(vld1q_f32(data + i), vdupq_n_f32(max_value))); + vst1q_f32(data + i, val); + sum += static_cast(vaddvq_f32(val)); + } #endif for (; i < count; ++i) { const float val = std::exp(data[i] - max_value); @@ -4196,8 +4385,8 @@ inline bool can_run_flash_attn_ext(const request_type &request) noexcept { return explicit_operand_contract && dims_present && src2_valid && shape_match && layout_supported && storage_bound && - masked_total_tokens >= kv_tokens && - std::isfinite(scale) && scale > 0.0f; + masked_total_tokens >= kv_tokens && std::isfinite(scale) && + scale > 0.0f; } //------------------------------------------------------------------------------// @@ -4638,8 +4827,8 @@ inline bool can_run_im2col(const request_type &request) noexcept { constexpr int64_t k_guard_cap = static_cast(k_max_conv_guard_extent); // Each bound keeps the next product under 2^62, so the chain evaluates // without signed overflow: factors first, then rows, then the batch total. - if (request.src1.ne[2] > k_max_conv_guard_extent || out_length > k_guard_cap || - row_width > k_guard_cap) { + if (request.src1.ne[2] > k_max_conv_guard_extent || + out_length > k_guard_cap || row_width > k_guard_cap) { return false; } if (out_length > 0 && batches > 0 && @@ -4649,8 +4838,7 @@ inline bool can_run_im2col(const request_type &request) noexcept { } const uint8_t src0_type = dtype_code(request.src0.type); return request.src1.data != nullptr && request.dst.data != nullptr && - kernel > 0 && channels > 0 && - length > 0 && out_length > 0 && + kernel > 0 && channels > 0 && length > 0 && out_length > 0 && (src0_type == dtype_f32 || src0_type == dtype_f16) && dtype_code(request.src1.type) == dtype_f32 && (dst_type == dtype_f32 || dst_type == dtype_f16) && @@ -4751,8 +4939,8 @@ inline bool can_run_conv_transpose_1d(const request_type &request) noexcept { // destination; metadata-only tensors must reject here instead of // dereferencing null inside the action. return request.src0.data != nullptr && request.src1.data != nullptr && - request.dst.data != nullptr && - kernel > 0 && out_channels > 0 && in_channels > 0 && length > 0 && + request.dst.data != nullptr && kernel > 0 && out_channels > 0 && + in_channels > 0 && length > 0 && (src0_type == dtype_f32 || src0_type == dtype_f16) && dtype_code(request.src1.type) == dtype_f32 && dtype_code(request.dst.type) == dtype_f32 && request.src0.ne[3] == 1 && diff --git a/src/emel/model/data.hpp b/src/emel/model/data.hpp index 0d85ac69..78a25b98 100644 --- a/src/emel/model/data.hpp +++ b/src/emel/model/data.hpp @@ -273,10 +273,13 @@ struct data { struct moshi_lm_hparams { static constexpr int32_t k_max_delays = 64; + static constexpr int32_t k_max_inference_prompt_tokens = k_max_delays; + static constexpr int32_t k_max_depformer_weight_schedule = k_max_delays; int32_t card = 0; int32_t n_q = 0; int32_t dep_q = 0; + int32_t inference_dep_q = 0; int32_t text_card = 0; int32_t text_padding_id = -1; int32_t dim = 0; @@ -293,8 +296,16 @@ struct data { int32_t depformer_max_period = 0; int32_t depformer_low_rank_embeddings = 0; int32_t extra_heads_num_heads = 0; + int32_t inference_pre_text_silence_frames = 0; + int32_t inference_post_text_silence_frames = 0; uint32_t delay_count = 0; + uint32_t inference_prompt_token_count = 0; + uint32_t depformer_weight_schedule_count = 0; std::array delays = {}; + std::array inference_prompt_tokens = + {}; + std::array + depformer_weight_schedule = {}; bool causal = false; bool cross_attention = false; bool demux_second_stream = false; diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index aeab6e19..f7efbbd8 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -1,5 +1,6 @@ #include "emel/model/moshi/detail.hpp" +#include #include #include #include @@ -112,6 +113,12 @@ bool assign_optional_i32(const emel::model::detail::kv_binding &binding, return require_u32_as_i32(binding, key, field); } +bool require_nonnegative_i32(const emel::model::detail::kv_binding &binding, + const std::string_view key, + int32_t &field) noexcept { + return require_u32_as_i32(binding, key, field) && field >= 0; +} + bool require_f32(const emel::model::detail::hparam_loader &loader, const std::string_view key, float &field) noexcept { const auto *entry = emel::model::detail::find_kv_entry(loader.binding, key); @@ -146,6 +153,59 @@ bool require_i32_array(const emel::model::detail::kv_binding &binding, return true; } +bool assign_optional_i32_array( + const emel::model::detail::kv_binding &binding, const std::string_view key, + const std::span dst, uint32_t &count_out) noexcept { + const auto *entry = emel::model::detail::find_kv_entry(binding, key); + if (entry == nullptr) { + count_out = 0u; + return true; + } + return require_i32_array(binding, key, dst, count_out); +} + +bool validate_lm_inference_hparams( + const emel::model::data::moshi_lm_hparams &lm) noexcept { + if (!lm.depformer_weights_per_step) { + return true; + } + + const uint32_t codebook_count = static_cast(lm.n_q) + 1u; + if (lm.inference_dep_q <= 0 || lm.inference_dep_q > lm.dep_q || + lm.inference_dep_q > lm.n_q || + lm.inference_prompt_token_count != codebook_count || + lm.inference_pre_text_silence_frames < 0 || + lm.inference_post_text_silence_frames < 0) { + return false; + } + + if (lm.inference_prompt_tokens[0] < 0 || + lm.inference_prompt_tokens[0] >= lm.text_card) { + return false; + } + for (uint32_t index = 1u; index < codebook_count; ++index) { + const int32_t token = lm.inference_prompt_tokens[index]; + if (token < 0 || token >= lm.card) { + return false; + } + } + + if (lm.depformer_weight_schedule_count > 0u) { + if (lm.depformer_weight_schedule_count != static_cast(lm.dep_q)) { + return false; + } + for (uint32_t index = 0u; index < lm.depformer_weight_schedule_count; + ++index) { + const int32_t weight_index = lm.depformer_weight_schedule[index]; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return false; + } + } + } + + return true; +} + bool load_lm_hparams(const emel::model::detail::hparam_loader &loader, emel::model::data &model_out) noexcept { auto &lm = model_out.moshi_lm; @@ -210,6 +270,10 @@ bool load_lm_hparams(const emel::model::detail::hparam_loader &loader, lm.depformer_multi_linear) || !require_bool(binding, "moshi.lm.depformer.weights_per_step", lm.depformer_weights_per_step) || + !assign_optional_i32_array( + binding, "moshi.lm.depformer.weights_per_step_schedule", + std::span{lm.depformer_weight_schedule}, + lm.depformer_weight_schedule_count) || !assign_optional_i32(binding, "moshi.lm.depformer.low_rank_embeddings", lm.depformer_low_rank_embeddings) || !lm.depformer_multi_linear || @@ -217,6 +281,25 @@ bool load_lm_hparams(const emel::model::detail::hparam_loader &loader, return false; } + if (lm.depformer_weights_per_step && + (!require_positive_i32(binding, "moshi.lm.inference.dep_q", + lm.inference_dep_q) || + !require_nonnegative_i32(binding, + "moshi.lm.inference.pre_text_silence_frames", + lm.inference_pre_text_silence_frames) || + !require_nonnegative_i32(binding, + "moshi.lm.inference.post_text_silence_frames", + lm.inference_post_text_silence_frames) || + !require_i32_array(binding, "moshi.lm.inference.prompt_tokens", + std::span{lm.inference_prompt_tokens}, + lm.inference_prompt_token_count))) { + return false; + } + + if (!validate_lm_inference_hparams(lm)) { + return false; + } + model_out.moshi_component_id = emel::model::data::moshi_component::lm; model_out.params.n_embd = lm.dim; model_out.params.n_embd_out = lm.dim; @@ -296,42 +379,23 @@ bool tensor_has_storage( return false; } - uint64_t rows = 1u; + std::array dims = {1u, 1u, 1u, 1u}; for (int32_t dim = 0; dim < tensor.n_dims; ++dim) { if (tensor.dims[static_cast(dim)] <= 0) { return false; } - const uint64_t extent = + dims[static_cast(dim)] = static_cast(tensor.dims[static_cast(dim)]); - if (dim > 0) { - if (extent > UINT64_MAX / rows) { - return false; - } - rows *= extent; - } - } - - const auto layout = - emel::gguf::loader::detail::ggml_layout( - static_cast(tensor.type)); - if (layout.block_size == 0u || layout.type_size == 0u) { - return false; } - const uint64_t cols = static_cast(tensor.dims[0]); - if (cols % layout.block_size != 0u) { - return false; - } - const uint64_t blocks_per_row = cols / layout.block_size; - if (blocks_per_row > UINT64_MAX / rows) { - return false; - } - const uint64_t blocks = blocks_per_row * rows; - if (blocks > UINT64_MAX / layout.type_size) { + uint64_t required_bytes = 0u; + const emel::error::type size_err = + emel::gguf::loader::detail::compute_tensor_data_size( + dims, static_cast(tensor.n_dims), + static_cast(tensor.type), required_bytes); + if (size_err != emel::error::cast(emel::gguf::loader::error::none)) { return false; } - const uint64_t required_bytes = - blocks * static_cast(layout.type_size); return tensor.data_size >= required_bytes; } @@ -353,16 +417,17 @@ bool tensor_has_lm_execution_storage( case 11: // Q3_K case 12: // Q4_K case 14: // Q6_K + case 42: // EMEL Q4_K x8 BL8 return true; default: return false; } } -bool assign_family_view(const emel::model::data &model_data, - const std::string_view prefix, - family_view &family_out, - const bool require_lm_execution_storage = false) noexcept { +bool assign_family_view( + const emel::model::data &model_data, const std::string_view prefix, + family_view &family_out, + const bool require_lm_execution_storage = false) noexcept { family_out = {}; family_out.prefix = prefix; @@ -456,8 +521,7 @@ bool has_projection_tensor(const emel::model::data &model_data, return false; } return q8_class ? tensor->type == k_dtype_q8_0 - : tensor->type == k_dtype_f32 || - tensor->type == k_dtype_f16; + : tensor->type == k_dtype_f32 || tensor->type == k_dtype_f16; } bool require_tensor_shape(const emel::model::data &model_data, @@ -527,8 +591,7 @@ bool has_depformer_block(const emel::model::data &model_data, block_index)); } -uint32_t -count_tensors_with_storage( +uint32_t count_tensors_with_storage( const emel::model::data &model_data, const bool require_lm_execution_storage = false) noexcept { uint32_t count = 0u; @@ -672,35 +735,31 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, "mimi.quantizer.rvq_first.vq.layers.%d." "_codebook.embedding", level); - quantizer_ok = written > 0 && static_cast(written) < sizeof(name) && - require_tensor_shape( - model_data, - std::string_view{name, static_cast(written)}, - {codebook_dim, card}) && - // bind_rvq_split consumes codebooks via tensor_is_float - has_float_tensor_with_elements( - model_data, - std::string_view{name, static_cast(written)}, - static_cast(codebook_dim) * - static_cast(card)); + quantizer_ok = + written > 0 && static_cast(written) < sizeof(name) && + require_tensor_shape( + model_data, std::string_view{name, static_cast(written)}, + {codebook_dim, card}) && + // bind_rvq_split consumes codebooks via tensor_is_float + has_float_tensor_with_elements( + model_data, std::string_view{name, static_cast(written)}, + static_cast(codebook_dim) * static_cast(card)); } - for (int32_t level = 0; - quantizer_ok && level < mimi.n_q - mimi.semantic_n_q; ++level) { + for (int32_t level = 0; quantizer_ok && level < mimi.n_q - mimi.semantic_n_q; + ++level) { char name[96] = {}; const int written = std::snprintf(name, sizeof(name), "mimi.quantizer.rvq_rest.vq.layers.%d." "_codebook.embedding", level); - quantizer_ok = written > 0 && static_cast(written) < sizeof(name) && - require_tensor_shape( - model_data, - std::string_view{name, static_cast(written)}, - {codebook_dim, card}) && - has_float_tensor_with_elements( - model_data, - std::string_view{name, static_cast(written)}, - static_cast(codebook_dim) * - static_cast(card)); + quantizer_ok = + written > 0 && static_cast(written) < sizeof(name) && + require_tensor_shape( + model_data, std::string_view{name, static_cast(written)}, + {codebook_dim, card}) && + has_float_tensor_with_elements( + model_data, std::string_view{name, static_cast(written)}, + static_cast(codebook_dim) * static_cast(card)); } if (!quantizer_ok) { return emel::error::cast(emel::model::loader::error::model_invalid); @@ -743,9 +802,9 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, for (int32_t layer = 0; transformers_ok && layer < mimi.transformer_num_layers; ++layer) { char base[96] = {}; - const int base_len = std::snprintf( - base, sizeof(base), "mimi.%s.transformer.layers.%d.", - k_transformer_families[family], layer); + const int base_len = + std::snprintf(base, sizeof(base), "mimi.%s.transformer.layers.%d.", + k_transformer_families[family], layer); if (base_len <= 0 || static_cast(base_len) >= sizeof(base)) { transformers_ok = false; break; @@ -791,34 +850,27 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, has_projection_tensor(model_data, layer_name("self_attn.in_projs.0.weight", name), dim_elements * 3u * dim_elements, proj_q8) && - has_projection_tensor(model_data, - layer_name("self_attn.out_projs.0.weight", - name), - dim_elements * dim_elements, proj_q8) && + has_projection_tensor( + model_data, layer_name("self_attn.out_projs.0.weight", name), + dim_elements * dim_elements, proj_q8) && has_projection_tensor(model_data, layer_name("linear2.weight", name), dim_elements * mlp_elements, proj_q8) && // norms, biases, and layer scales bind through prepare_vector, // which accepts only f32/f16. - has_float_tensor_with_elements(model_data, - layer_name("norm1.weight", name), - dim_elements) && - has_float_tensor_with_elements(model_data, - layer_name("norm1.bias", name), - dim_elements) && - has_float_tensor_with_elements(model_data, - layer_name("norm2.weight", name), - dim_elements) && - has_float_tensor_with_elements(model_data, - layer_name("norm2.bias", name), - dim_elements) && - has_float_tensor_with_elements(model_data, - layer_name("layer_scale_1.scale", - name), - dim_elements) && - has_float_tensor_with_elements(model_data, - layer_name("layer_scale_2.scale", - name), - dim_elements); + has_float_tensor_with_elements( + model_data, layer_name("norm1.weight", name), dim_elements) && + has_float_tensor_with_elements( + model_data, layer_name("norm1.bias", name), dim_elements) && + has_float_tensor_with_elements( + model_data, layer_name("norm2.weight", name), dim_elements) && + has_float_tensor_with_elements( + model_data, layer_name("norm2.bias", name), dim_elements) && + has_float_tensor_with_elements( + model_data, layer_name("layer_scale_1.scale", name), + dim_elements) && + has_float_tensor_with_elements( + model_data, layer_name("layer_scale_2.scale", name), + dim_elements); } } if (!transformers_ok) { @@ -839,8 +891,8 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, find_tensor(model_data, "mimi.encoder.model.0.conv.conv.weight"); const bool conv_f16 = first_conv != nullptr && first_conv->type == k_dtype_f16; - const uint64_t proj_elements = - static_cast(mimi.dim) * static_cast(mimi.codebook_dim); + const uint64_t proj_elements = static_cast(mimi.dim) * + static_cast(mimi.codebook_dim); const auto *first_rvq_proj = find_tensor(model_data, "mimi.quantizer.rvq_first.input_proj.weight"); const bool rvq_q8 = @@ -867,12 +919,11 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, for (size_t split = 0; projections_ok && split < 2u; ++split) { char name[96] = {}; const int in_len = - std::snprintf(name, sizeof(name), - "mimi.quantizer.%s.input_proj.weight", k_rvq_splits[split]); + std::snprintf(name, sizeof(name), "mimi.quantizer.%s.input_proj.weight", + k_rvq_splits[split]); projections_ok = in_len > 0 && static_cast(in_len) < sizeof(name) && - rvq_projection_ok( - std::string_view{name, static_cast(in_len)}); + rvq_projection_ok(std::string_view{name, static_cast(in_len)}); if (!projections_ok) { break; } @@ -881,8 +932,7 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, k_rvq_splits[split]); projections_ok = out_len > 0 && static_cast(out_len) < sizeof(name) && - rvq_projection_ok( - std::string_view{name, static_cast(out_len)}); + rvq_projection_ok(std::string_view{name, static_cast(out_len)}); } if (!projections_ok) { return emel::error::cast(emel::model::loader::error::model_invalid); @@ -897,11 +947,11 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, // stride otherwise validates and fails codec initialization. plan_codec // also selects the f16 conv operand class from the first encoder conv and // bind_conv requires raw f16 taps on every non-transposed conv. - const auto resolve_conv = [&model_data, conv_f16]( - const std::string_view name, - const int64_t in_channels, - const bool transposed, int64_t &taps_out, - int64_t &out_channels_out) noexcept { + const auto resolve_conv = [&model_data, + conv_f16](const std::string_view name, + const int64_t in_channels, + const bool transposed, int64_t &taps_out, + int64_t &out_channels_out) noexcept { const auto *weight = find_tensor(model_data, name); constexpr int32_t k_dtype_f32 = 0; if (weight == nullptr || !tensor_has_storage(*weight) || @@ -941,17 +991,18 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, int32_t stride; }; static constexpr seanet_module k_encoder_modules[] = { - {0, 0, 1}, {1, 2, 1}, {3, 0, 4}, {4, 2, 1}, {6, 0, 5}, + {0, 0, 1}, {1, 2, 1}, {3, 0, 4}, {4, 2, 1}, {6, 0, 5}, {7, 2, 1}, {9, 0, 6}, {10, 2, 1}, {12, 0, 8}, {14, 0, 1}, }; static constexpr seanet_module k_decoder_modules[] = { - {0, 0, 1}, {2, 1, 8}, {3, 2, 1}, {5, 1, 6}, {6, 2, 1}, + {0, 0, 1}, {2, 1, 8}, {3, 2, 1}, {5, 1, 6}, {6, 2, 1}, {8, 1, 5}, {9, 2, 1}, {11, 1, 4}, {12, 2, 1}, {14, 0, 1}, }; - const auto walk_seanet = [&resolve_conv](const char *family, - std::span modules, - int64_t channels, - int64_t &channels_out) noexcept { + const auto walk_seanet = [&resolve_conv]( + const char *family, + std::span modules, + int64_t channels, + int64_t &channels_out) noexcept { for (const seanet_module &module : modules) { char name[112] = {}; if (module.kind == 2u) { @@ -999,8 +1050,8 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, int64_t decoder_channels = 0; int64_t down_taps = 0; int64_t down_out = 0; - const auto *upsample = find_tensor( - model_data, "mimi.upsample.convtr.convtr.convtr.weight"); + const auto *upsample = + find_tensor(model_data, "mimi.upsample.convtr.convtr.convtr.weight"); uint64_t upsample_elements = 0u; if (upsample != nullptr && tensor_has_storage(*upsample)) { upsample_elements = 1u; @@ -1010,12 +1061,10 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, } } const bool seanet_ok = - walk_seanet("encoder", - std::span{k_encoder_modules}, + walk_seanet("encoder", std::span{k_encoder_modules}, 1, encoder_channels) && encoder_channels == dim && - walk_seanet("decoder", - std::span{k_decoder_modules}, + walk_seanet("decoder", std::span{k_decoder_modules}, dim, decoder_channels) && decoder_channels == 1 && resolve_conv("mimi.downsample.conv.conv.conv.weight", dim, false, @@ -1047,7 +1096,6 @@ emel::error::type validate_mimi_contract(const emel::model::data &model_data, return emel::error::cast(emel::model::loader::error::model_invalid); } - return emel::error::cast(emel::model::loader::error::none); } diff --git a/src/emel/speech/codec/mimi/detail.cpp b/src/emel/speech/codec/mimi/detail.cpp index d698c0ef..ad29145b 100644 --- a/src/emel/speech/codec/mimi/detail.cpp +++ b/src/emel/speech/codec/mimi/detail.cpp @@ -60,8 +60,7 @@ tensor_elements(const emel::model::data::tensor_record &tensor) noexcept { uint64_t count = 1; for (int32_t dim = 0; dim < tensor.n_dims; ++dim) { const int64_t extent = tensor.dims[static_cast(dim)]; - if (extent <= 0 || - static_cast(extent) > UINT64_MAX / count) { + if (extent <= 0 || static_cast(extent) > UINT64_MAX / count) { return 0u; } count *= static_cast(extent); @@ -428,16 +427,6 @@ bool dispatch_add(codec_runtime &runtime, const kev::tensor_view &lhs, return runtime.kernel.process_event(ev); } -bool dispatch_sub(codec_runtime &runtime, const kev::tensor_view &lhs, - const kev::tensor_view &rhs, - const kev::tensor_view_mut &dst) noexcept { - kev::op_sub ev{}; - ev.src0 = lhs; - ev.src1 = rhs; - ev.dst = dst; - return runtime.kernel.process_event(ev); -} - bool dispatch_mul_mat(codec_runtime &runtime, const kev::tensor_view &src0, const kev::tensor_view &src1, const kev::tensor_view_mut &dst) noexcept { @@ -1198,15 +1187,13 @@ void compute_rvq_encode(codec_runtime &runtime, const frame_buffer &latent, static_cast(n_q) * static_cast(frames)) { return; } - const uint64_t need = 2u * static_cast(codebook_dim) + 2u + + const uint64_t need = static_cast(codebook_dim) + (static_cast(dim) + 1u) / 2u + 1u; if (workspace.size() < need) { return; } - float *residual = workspace.data(); // [codebook_dim + 1] with trailing 1 - float *chosen = residual + codebook_dim + 1; - auto *staged_f16 = - reinterpret_cast(chosen + codebook_dim + 1); // [dim] halfs + float *residual = workspace.data(); // [codebook_dim] + auto *staged_f16 = reinterpret_cast(residual + codebook_dim); for (int64_t frame = 0; frame < frames; ++frame) { const float *x = latent.data + frame * dim; @@ -1217,7 +1204,7 @@ void compute_rvq_encode(codec_runtime &runtime, const frame_buffer &latent, if (split->level_count <= 0) { continue; } - // project into codebook space; append the bias-fold constant + // project into codebook space bool projected_in = false; if constexpr (proj_q8) { projected_in = dispatch_q8_matvec(runtime, split->input_proj_q8, dim, @@ -1244,43 +1231,39 @@ void compute_rvq_encode(codec_runtime &runtime, const frame_buffer &latent, if (!projected_in) { return; } - residual[codebook_dim] = 1.0f; for (int32_t level = 0; level < split->level_count; ++level) { - int32_t index = -1; - float score = 0.0f; - kev::op_mul_mat_argmax argmax_ev{}; - argmax_ev.src0 = - make_view(split->search_tables[static_cast(level)], - static_cast(codebook_dim) + 1u, - static_cast(entries)); - argmax_ev.src1 = - make_view(residual, 1u, static_cast(codebook_dim) + 1u); - argmax_ev.dst = make_view_mut(&score, 1u, 1u); - argmax_ev.index_out = &index; - if (!runtime.kernel.process_event(argmax_ev) || index < 0) { + const float *codebook = split->codebooks[static_cast(level)]; + if (codebook == nullptr || entries <= 0 || codebook_dim <= 0) { return; } + int32_t index = 0; + float best_distance = 0.0f; + const float *first_entry = codebook; + for (int64_t c = 0; c < codebook_dim; ++c) { + const float diff = first_entry[c] - residual[c]; + best_distance += diff * diff; + } + for (int64_t entry = 1; entry < entries; ++entry) { + const float *candidate = codebook + entry * codebook_dim; + float distance = 0.0f; + for (int64_t c = 0; c < codebook_dim; ++c) { + const float diff = candidate[c] - residual[c]; + distance += diff * diff; + } + if (distance < best_distance) { + best_distance = distance; + index = static_cast(entry); + } + } codes_out[static_cast(code_row * frames + frame)] = index; ++code_row; if (level + 1 < split->level_count) { - kev::op_get_rows rows_ev{}; - rows_ev.src0 = make_view(split->codebooks[static_cast(level)], - static_cast(codebook_dim), - static_cast(entries)); - rows_ev.src1 = make_view(reinterpret_cast(&index), 1u); - rows_ev.src1.type = kev::dtype::i32; - rows_ev.dst = - make_view_mut(chosen, static_cast(codebook_dim), 1u); - if (!runtime.kernel.process_event(rows_ev) || - !dispatch_sub( - runtime, - make_view(residual, static_cast(codebook_dim)), - make_view(chosen, static_cast(codebook_dim)), - make_view_mut(residual, - static_cast(codebook_dim)))) { - return; + const float *chosen = + codebook + static_cast(index) * codebook_dim; + for (int64_t c = 0; c < codebook_dim; ++c) { + residual[c] -= chosen[c]; } } } @@ -1300,9 +1283,14 @@ void compute_rvq_decode(codec_runtime &runtime, std::span codes, const int64_t dim = runtime.dim; const int64_t codebook_dim = quantizer.codebook_dim; const int64_t entries = quantizer.codebook_entries; - const int64_t n_q = runtime.n_q; - if (frames <= 0 || - codes.size() < static_cast(n_q) * static_cast(frames)) { + const int64_t semantic_levels = quantizer.semantic.level_count; + if (frames <= 0 || codes.empty() || + codes.size() % static_cast(frames) != 0u) { + return; + } + const int64_t decode_n_q = + static_cast(codes.size() / static_cast(frames)); + if (decode_n_q < semantic_levels || decode_n_q > runtime.n_q) { return; } const uint64_t need = 2u * static_cast(codebook_dim) + @@ -1322,13 +1310,23 @@ void compute_rvq_decode(codec_runtime &runtime, std::span codes, std::memset(out, 0, static_cast(dim) * sizeof(float)); const rvq_split_weights *splits[2] = {&quantizer.semantic, &quantizer.acoustic}; + const int32_t split_levels[2] = { + static_cast(semantic_levels), + static_cast(decode_n_q - semantic_levels), + }; int64_t code_row = 0; - for (const rvq_split_weights *split : splits) { - if (split->level_count <= 0) { + for (int32_t split_index = 0; split_index < 2; ++split_index) { + const rvq_split_weights *split = splits[static_cast(split_index)]; + const int32_t active_levels = + split_levels[static_cast(split_index)]; + if (active_levels <= 0) { continue; } + if (active_levels > split->level_count) { + return; + } std::memset(summed, 0, static_cast(codebook_dim) * sizeof(float)); - for (int32_t level = 0; level < split->level_count; ++level) { + for (int32_t level = 0; level < active_levels; ++level) { const int32_t index = codes[static_cast(code_row * frames + frame)]; ++code_row; @@ -1386,7 +1384,7 @@ void compute_rvq_decode(codec_runtime &runtime, std::span codes, return; } } - if (code_row != n_q) { + if (code_row != decode_n_q) { return; } } @@ -2026,10 +2024,9 @@ bool bind_transformer(arena_cursor_t &cursor, uint64_t &state_cursor, template bool bind_rvq_split(arena_cursor_t &cursor, - const emel::model::data &model_data, - const char *split, const int32_t level_count, - const bool with_f16, const bool with_q8, - rvq_split_weights &split_out) noexcept { + const emel::model::data &model_data, const char *split, + const int32_t level_count, const bool with_f16, + const bool with_q8, rvq_split_weights &split_out) noexcept { // The per-level codebook/search-table arrays are k_max_quantizer_levels // wide; a split larger than that is out of contract regardless of which // tensors the model carries. @@ -2101,26 +2098,19 @@ bool bind_rvq_split(arena_cursor_t &cursor, } float *codebook = cursor.take(static_cast(cb_dim) * static_cast(entries)); - float *table = cursor.take((static_cast(cb_dim) + 1u) * - static_cast(entries)); - if (codebook == nullptr || table == nullptr) { + if (codebook == nullptr) { return false; } if constexpr (!dry_run) { for (int64_t entry = 0; entry < entries; ++entry) { - float norm2 = 0.0f; for (int64_t component = 0; component < cb_dim; ++component) { const float value = source_value( *embedding, static_cast(component + entry * cb_dim)); codebook[component + entry * cb_dim] = value; - table[component + entry * (cb_dim + 1)] = value; - norm2 += value * value; } - table[cb_dim + entry * (cb_dim + 1)] = -0.5f * norm2; } } split_out.codebooks[static_cast(level)] = codebook; - split_out.search_tables[static_cast(level)] = table; } return true; } @@ -2319,8 +2309,9 @@ bool validate_codec_contract(const emel::model::data &model_data) noexcept { bool validate_codes_in_range(const codec_runtime &runtime, std::span codes) noexcept { const int32_t entries = runtime.quantizer.codebook_entries; - const size_t count = static_cast(runtime.n_q); - if (codes.size() < count) { + const size_t count = codes.size(); + if (count == 0u || count > static_cast(runtime.n_q) || + count < static_cast(runtime.quantizer.semantic.level_count)) { return false; } for (size_t index = 0; index < count; ++index) { diff --git a/src/emel/speech/codec/mimi/detail.hpp b/src/emel/speech/codec/mimi/detail.hpp index 2170928a..99b9d893 100644 --- a/src/emel/speech/codec/mimi/detail.hpp +++ b/src/emel/speech/codec/mimi/detail.hpp @@ -154,9 +154,9 @@ struct transformer_weights { }; // One RVQ split (rvq_first carries the semantic level, rvq_rest the acoustic -// levels). Codebook search operands are prepared at bind time: the argmax -// score for level codebooks is x . c - |c|^2 / 2, so the prepared table -// appends the bias column and the input vector a trailing 1. +// levels). Codebook rows stay in reference layout; encode scans them with the +// reference squared-distance arithmetic so near-tie argmax behavior does not +// drift from ggml. struct rvq_split_weights { const float *input_proj = nullptr; // [dim, codebook_dim] (conv1x1) const float *output_proj = nullptr; // [codebook_dim, dim] @@ -166,9 +166,7 @@ struct rvq_split_weights { // raw q8_0 row blocks when the model carries quantized projections const uint8_t *input_proj_q8 = nullptr; const uint8_t *output_proj_q8 = nullptr; - // per level: prepared search table [codebook_dim + 1, entries] and raw - // codebook rows [codebook_dim, entries] - std::array search_tables = {}; + // per level: raw codebook rows [codebook_dim, entries] std::array codebooks = {}; int32_t level_count = 0; }; @@ -258,8 +256,8 @@ uint64_t required_frame_floats(const emel::model::data &model_data) noexcept; bool validate_codec_contract(const emel::model::data &model_data) noexcept; // Pure per-request validator for decode codes: every code addresses a valid -// codebook entry. Bounded scan over n_q codes; guards route on this before -// the decode action runs. +// codebook entry, and the request carries a valid codebook prefix. Bounded +// scan; guards route on this before the decode action runs. bool validate_codes_in_range(const codec_runtime &runtime, std::span codes) noexcept; @@ -328,7 +326,7 @@ void compute_rvq_encode(codec_runtime &runtime, const frame_buffer &latent, std::span codes_out, std::span workspace) noexcept; -// codes [n_q, frames] -> latent [dim, frames] +// codes [active_n_q, frames] -> latent [dim, frames] template void compute_rvq_decode(codec_runtime &runtime, std::span codes, int32_t frames, frame_buffer &latent_out, diff --git a/src/emel/speech/codec/mimi/guards.hpp b/src/emel/speech/codec/mimi/guards.hpp index fd5d723c..e2a3f5e6 100644 --- a/src/emel/speech/codec/mimi/guards.hpp +++ b/src/emel/speech/codec/mimi/guards.hpp @@ -38,7 +38,8 @@ struct guard_arena_capacity_valid { request.frame.data() != nullptr && request.prepared.size() >= detail::required_prepared_floats(model) && request.state_arena.size() >= detail::required_state_floats(model) && - request.workspace.size() >= detail::required_workspace_floats(model) && + request.workspace.size() >= + detail::required_workspace_floats(model) && request.frame.size() >= detail::required_frame_floats(model); } }; @@ -79,9 +80,12 @@ struct guard_decode_request_valid { const action::context &ctx) const noexcept { const auto &request = runtime_ev.request; // Mirror of the encode guard: codes are read and pcm_out is written. + const size_t code_count = request.codes.size(); return request.codes.data() != nullptr && request.pcm_out.data() != nullptr && - request.codes.size() >= static_cast(ctx.runtime.n_q) && + code_count >= static_cast( + ctx.runtime.quantizer.semantic.level_count) && + code_count <= static_cast(ctx.runtime.n_q) && request.pcm_out.size() >= static_cast(ctx.runtime.frame_samples); } diff --git a/src/emel/speech/codec/mimi/quantizer/guards.hpp b/src/emel/speech/codec/mimi/quantizer/guards.hpp index c2e2324a..7031d809 100644 --- a/src/emel/speech/codec/mimi/quantizer/guards.hpp +++ b/src/emel/speech/codec/mimi/quantizer/guards.hpp @@ -64,10 +64,13 @@ struct guard_decode_shape_valid { bool operator()(const event::decode_run &runtime_ev, const action::context &) const noexcept { const auto &request = runtime_ev.request; + const size_t code_count = request.codes.size(); return request.codes.data() != nullptr && request.latent_out.data() != nullptr && request.workspace.data() != nullptr && - request.codes.size() >= static_cast(request.runtime.n_q) && + code_count >= static_cast( + request.runtime.quantizer.semantic.level_count) && + code_count <= static_cast(request.runtime.n_q) && request.latent_out.size() >= static_cast(request.runtime.dim) && request.workspace.size() >= diff --git a/src/emel/speech/generator/moshi/actions.hpp b/src/emel/speech/generator/moshi/actions.hpp new file mode 100644 index 00000000..fb4a7d59 --- /dev/null +++ b/src/emel/speech/generator/moshi/actions.hpp @@ -0,0 +1,952 @@ +#pragma once + +#include +#include +#include +#include + +#include "emel/kernel/detail.hpp" +#include "emel/memory/events.hpp" +#include "emel/model/moshi/detail.hpp" +#include "emel/speech/generator/moshi/context.hpp" +#include "emel/speech/generator/moshi/detail.hpp" +#include "emel/speech/generator/moshi/events.hpp" + +namespace emel::speech::generator::moshi::action { + +namespace detail_ns { + +inline emel::error::type to_error(const error value) noexcept { + return emel::error::cast(value); +} + +} // namespace detail_ns + +template struct effect_mark_not_initialized { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::not_initialized); + } +}; + +struct effect_mark_bind_failed { + void operator()(const event::initialize_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::bind_failed); + } +}; + +template struct effect_mark_memory_error { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::memory); + } +}; + +struct effect_mark_step_request_invalid { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::request_shape); + } +}; + +template +struct effect_mark_graph_runtime_unavailable { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::graph_runtime_unavailable); + } +}; + +template struct effect_mark_graph_runtime_error { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::graph_runtime); + } +}; + +template struct effect_mark_voice_contract_error { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::voice_contract); + } +}; + +template +struct effect_mark_personaplex_prompt_error { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::personaplex_prompt); + } +}; + +struct effect_mark_voice_prompt_pending { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::voice_prompt_pending); + } +}; + +struct effect_bind_contract { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.session = {}; + ctx.session.model = &runtime_ev.request.model; + ctx.session.sequence_id = runtime_ev.request.sequence_id; + ctx.session.n_q = runtime_ev.request.model.moshi_lm.n_q; + ctx.session.dep_q = runtime_ev.request.model.moshi_lm.dep_q; + ctx.session.text_card = runtime_ev.request.model.moshi_lm.text_card; + ctx.session.audio_card = runtime_ev.request.model.moshi_lm.card; + (void)emel::model::moshi::detail::build_execution_contract( + runtime_ev.request.model, ctx.session.contract); + + const auto &lm = runtime_ev.request.model.moshi_lm; + ctx.lmgen = {}; + ctx.lmgen.codebook_count = lm.n_q + 1; + ctx.lmgen.generated_dep_q = lm.dep_q; + ctx.lmgen.cache_row_count = 2; + std::fill(ctx.lmgen.cache.begin(), ctx.lmgen.cache.end(), + k_token_ungenerated); + std::fill(ctx.lmgen.initial.begin(), ctx.lmgen.initial.end(), lm.card); + ctx.lmgen.initial[0] = lm.text_card; + for (uint32_t index = 0; index < lm.delay_count; ++index) { + ctx.lmgen.delays[index] = lm.delays[index]; + ctx.lmgen.max_delay = std::max(ctx.lmgen.max_delay, lm.delays[index]); + } + ctx.lmgen.cache_row_count = ctx.lmgen.max_delay + 2 + ctx.lmgen.delay_steps; + } +}; + +struct effect_configure_standard_lmgen { + void operator()(const event::initialize_run &, context &ctx) const noexcept { + ctx.lmgen.delayed_dep_q = ctx.lmgen.generated_dep_q; + ctx.lmgen.needed_tokens = + ctx.lmgen.codebook_count - ctx.lmgen.delayed_dep_q - 1; + } +}; + +struct effect_configure_personaplex_lmgen { + void operator()(const event::initialize_run &, context &ctx) const noexcept { + ctx.lmgen.delayed_dep_q = ctx.session.model->moshi_lm.inference_dep_q; + ctx.lmgen.needed_tokens = + ctx.lmgen.codebook_count - ctx.lmgen.delayed_dep_q - 1; + ctx.lmgen.cache_row_count = ctx.lmgen.max_delay + 3; + } +}; + +struct effect_bind_voice_contract { + void operator()(const event::load_voice_run &runtime_ev, + context &ctx) const noexcept { + ctx.voice = {}; + ctx.voice.model = &runtime_ev.request.voice_model; + (void)emel::model::moshi::detail::build_execution_contract( + runtime_ev.request.voice_model, ctx.voice.contract); + const auto *embeddings = ctx.voice.contract.voice.embeddings.tensor; + const auto *cache = ctx.voice.contract.voice.cache.tensor; + ctx.voice.embedding_dim = static_cast(embeddings->dims[0]); + ctx.voice.prompt_frame_count = static_cast(embeddings->dims[3]); + ctx.voice.prompt_frame_index = 0; + ctx.voice.cache_row_count = static_cast(cache->dims[0]); + ctx.voice.cache_column_count = static_cast(cache->dims[1]); + ctx.voice.loaded = true; + ctx.voice.ready = false; + } +}; + +struct effect_reserve_memory { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::reserve{ + .max_sequences = runtime_ev.request.max_sequences, + .max_blocks = runtime_ev.request.max_blocks, + .block_tokens = runtime_ev.request.block_tokens, + .error_out = &runtime_ev.ctx.memory_error, + }); + } +}; + +struct effect_allocate_sequence { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::allocate_sequence{ + .seq_id = runtime_ev.request.sequence_id, + .error_out = &runtime_ev.ctx.memory_error, + }); + } +}; + +struct effect_allocate_step_slot { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_block_count = 0; + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::allocate_slots{ + .seq_id = ctx.session.sequence_id, + .token_count = 1, + .block_count_out = &runtime_ev.ctx.memory_block_count, + .error_out = &runtime_ev.ctx.memory_error, + .copy_block = nullptr, + .copy_block_user_data = nullptr, + }); + } +}; + +struct effect_capture_memory { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::capture_view{ + .snapshot_out = &runtime_ev.ctx.memory_snapshot, + .error_out = &runtime_ev.ctx.memory_error, + }); + } +}; + +struct effect_allocate_voice_prefill_slot { + void operator()(const event::prefill_voice_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_block_count = 0; + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::allocate_slots{ + .seq_id = ctx.session.sequence_id, + .token_count = 1, + .block_count_out = &runtime_ev.ctx.memory_block_count, + .error_out = &runtime_ev.ctx.memory_error, + .copy_block = nullptr, + .copy_block_user_data = nullptr, + }); + } +}; + +struct effect_capture_voice_prefill_memory { + void operator()(const event::prefill_voice_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::capture_view{ + .snapshot_out = &runtime_ev.ctx.memory_snapshot, + .error_out = &runtime_ev.ctx.memory_error, + }); + } +}; + +struct effect_begin_voice_prefill { + void operator()(const event::prefill_voice_run &runtime_ev, + const context &ctx) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_accepted = false; + runtime_ev.ctx.embedding_frame_ok = false; + runtime_ev.ctx.complete = ctx.voice.ready; + runtime_ev.ctx.remaining_frames = + ctx.voice.prompt_frame_count - ctx.voice.prompt_frame_index; + runtime_ev.ctx.text_token = ctx.session.model->moshi_lm.text_padding_id; + std::fill(runtime_ev.ctx.input_sequence.begin(), + runtime_ev.ctx.input_sequence.end(), k_token_zero); + runtime_ev.ctx.input_sequence[0] = + ctx.session.model->moshi_lm.text_padding_id; + std::fill(runtime_ev.ctx.audio_tokens.begin(), + runtime_ev.ctx.audio_tokens.end(), k_token_zero); + } +}; + +struct effect_load_voice_embedding_frame_f32 { + void operator()(const event::prefill_voice_run &runtime_ev, + const context &ctx) const noexcept { + const auto *tensor = ctx.voice.contract.voice.embeddings.tensor; + const auto *src = static_cast(tensor->data); + const int32_t dim = ctx.voice.embedding_dim; + const size_t offset = static_cast(ctx.voice.prompt_frame_index) * + static_cast(dim); + for (int32_t index = 0; index < dim; ++index) { + runtime_ev.ctx.embedding_frame[static_cast(index)] = + src[offset + static_cast(index)]; + } + runtime_ev.ctx.embedding_frame_ok = true; + } +}; + +struct effect_load_voice_embedding_frame_f16 { + void operator()(const event::prefill_voice_run &runtime_ev, + const context &ctx) const noexcept { + const auto *tensor = ctx.voice.contract.voice.embeddings.tensor; + const auto *src = static_cast(tensor->data); + const int32_t dim = ctx.voice.embedding_dim; + const size_t offset = static_cast(ctx.voice.prompt_frame_index) * + static_cast(dim); + for (int32_t index = 0; index < dim; ++index) { + runtime_ev.ctx.embedding_frame[static_cast(index)] = + emel::kernel::detail::quant::fp16_to_fp32( + src[offset + static_cast(index)]); + } + runtime_ev.ctx.embedding_frame_ok = true; + } +}; + +struct effect_load_voice_embedding_frame_bf16 { + void operator()(const event::prefill_voice_run &runtime_ev, + const context &ctx) const noexcept { + const auto *tensor = ctx.voice.contract.voice.embeddings.tensor; + const auto *src = static_cast(tensor->data); + const int32_t dim = ctx.voice.embedding_dim; + const size_t offset = static_cast(ctx.voice.prompt_frame_index) * + static_cast(dim); + for (int32_t index = 0; index < dim; ++index) { + runtime_ev.ctx.embedding_frame[static_cast(index)] = + emel::kernel::detail::bf16_to_fp32( + src[offset + static_cast(index)]); + } + runtime_ev.ctx.embedding_frame_ok = true; + } +}; + +struct effect_run_voice_graph_runtime { + void operator()(const event::prefill_voice_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + event::graph_step graph_step{ + *ctx.session.model, + runtime_ev.ctx.memory_snapshot, + std::span{runtime_ev.ctx.input_sequence.data(), + static_cast(ctx.lmgen.codebook_count)}, + std::span{runtime_ev.ctx.audio_tokens.data(), + static_cast(ctx.lmgen.generated_dep_q)}, + runtime_ev.ctx.text_token, + }; + graph_step.sequence_id = ctx.session.sequence_id; + graph_step.input_embedding = + std::span{runtime_ev.ctx.embedding_frame.data(), + static_cast(ctx.voice.embedding_dim)}; + graph_step.forced_text_token = ctx.session.model->moshi_lm.text_padding_id; + graph_step.error_out = &runtime_ev.ctx.graph_error; + runtime_ev.ctx.graph_accepted = + ctx.graph.dispatch_step(ctx.graph.executor, graph_step); + } +}; + +struct effect_advance_voice_prefill { + void operator()(const event::prefill_voice_run &runtime_ev, + context &ctx) const noexcept { + ++ctx.voice.prompt_frame_index; + ++ctx.lmgen.offset; + runtime_ev.ctx.remaining_frames = + ctx.voice.prompt_frame_count - ctx.voice.prompt_frame_index; + runtime_ev.ctx.complete = + ctx.voice.prompt_frame_index >= ctx.voice.prompt_frame_count; + } +}; + +struct effect_copy_voice_cache { + void operator()(const event::prefill_voice_run &runtime_ev, + context &ctx) const noexcept { + const auto *tensor = ctx.voice.contract.voice.cache.tensor; + const auto *src = static_cast(tensor->data); + for (int32_t row = 0; row < ctx.voice.cache_row_count; ++row) { + for (int32_t column = 0; column < ctx.voice.cache_column_count; + ++column) { + const size_t source_index = + static_cast(row) + + static_cast(column) * + static_cast(ctx.voice.cache_row_count); + detail::cache_at(ctx.lmgen, row, column) = src[source_index]; + } + } + ctx.voice.ready = true; + runtime_ev.ctx.complete = true; + runtime_ev.ctx.remaining_frames = 0; + } +}; + +struct effect_bind_personaplex_prompt { + void operator()(const event::begin_personaplex_prompt_run &runtime_ev, + context &ctx) const noexcept { + ctx.voice.pre_text_silence_remaining = + runtime_ev.request.pre_text_silence_frames; + ctx.voice.text_tokens_remaining = runtime_ev.request.text_token_count; + ctx.voice.post_text_silence_remaining = + runtime_ev.request.post_text_silence_frames; + ctx.voice.prompt_started = true; + ctx.voice.prompt_ready = false; + runtime_ev.ctx.remaining_frames = ctx.voice.pre_text_silence_remaining + + ctx.voice.text_tokens_remaining + + ctx.voice.post_text_silence_remaining; + } +}; + +struct effect_bind_empty_personaplex_prompt { + void operator()(const event::begin_personaplex_prompt_run &runtime_ev, + context &ctx) const noexcept { + const auto &lm = ctx.session.model->moshi_lm; + ctx.voice.pre_text_silence_remaining = lm.inference_pre_text_silence_frames; + ctx.voice.text_tokens_remaining = 0; + ctx.voice.post_text_silence_remaining = + lm.inference_post_text_silence_frames; + ctx.voice.prompt_started = true; + ctx.voice.prompt_ready = false; + runtime_ev.ctx.remaining_frames = ctx.voice.pre_text_silence_remaining + + ctx.voice.post_text_silence_remaining; + } +}; + +struct effect_allocate_personaplex_prompt_slot { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_block_count = 0; + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::allocate_slots{ + .seq_id = ctx.session.sequence_id, + .token_count = 1, + .block_count_out = &runtime_ev.ctx.memory_block_count, + .error_out = &runtime_ev.ctx.memory_error, + .copy_block = nullptr, + .copy_block_user_data = nullptr, + }); + } +}; + +struct effect_capture_personaplex_prompt_memory { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::capture_view{ + .snapshot_out = &runtime_ev.ctx.memory_snapshot, + .error_out = &runtime_ev.ctx.memory_error, + }); + } +}; + +struct effect_begin_personaplex_prompt_prefill { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const context &ctx) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_accepted = false; + runtime_ev.ctx.complete = false; + runtime_ev.ctx.remaining_frames = ctx.voice.pre_text_silence_remaining + + ctx.voice.text_tokens_remaining + + ctx.voice.post_text_silence_remaining; + runtime_ev.ctx.text_token = ctx.session.model->moshi_lm.text_padding_id; + std::fill(runtime_ev.ctx.prompt_sequence.begin(), + runtime_ev.ctx.prompt_sequence.end(), k_token_zero); + std::fill(runtime_ev.ctx.input_sequence.begin(), + runtime_ev.ctx.input_sequence.end(), k_token_zero); + std::fill(runtime_ev.ctx.audio_tokens.begin(), + runtime_ev.ctx.audio_tokens.end(), k_token_zero); + } +}; + +struct effect_build_personaplex_prompt_silence_frame { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const context &ctx) const noexcept { + for (int32_t index = 0; index < ctx.lmgen.codebook_count; ++index) { + runtime_ev.ctx.prompt_sequence[static_cast(index)] = + ctx.session.model->moshi_lm + .inference_prompt_tokens[static_cast(index)]; + } + } +}; + +struct effect_build_personaplex_prompt_text_frame { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const context &ctx) const noexcept { + effect_build_personaplex_prompt_silence_frame{}(runtime_ev, ctx); + runtime_ev.ctx.prompt_sequence[0] = runtime_ev.request.text_token; + } +}; + +struct effect_write_and_build_personaplex_prompt_input { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &ctx) const noexcept { + for (int32_t index = 0; index < ctx.lmgen.codebook_count; ++index) { + const int32_t write_row = detail::cache_position( + ctx.lmgen, ctx.lmgen.offset + ctx.lmgen.delays[index]); + detail::cache_at(ctx.lmgen, write_row, index) = + runtime_ev.ctx.prompt_sequence[static_cast(index)]; + } + + const int32_t read_row = + detail::cache_position(ctx.lmgen, ctx.lmgen.offset); + for (int32_t index = 0; index < ctx.lmgen.codebook_count; ++index) { + const bool use_initial = ctx.lmgen.offset <= ctx.lmgen.delays[index]; + const int32_t initial_lane = static_cast(use_initial); + const int32_t cache_lane = static_cast(!use_initial); + runtime_ev.ctx.input_sequence[static_cast(index)] = + (initial_lane * ctx.lmgen.initial[index]) + + (cache_lane * detail::cache_at(ctx.lmgen, read_row, index)); + } + } +}; + +struct effect_run_personaplex_prompt_graph_runtime { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + event::graph_step graph_step{ + *ctx.session.model, + runtime_ev.ctx.memory_snapshot, + std::span{runtime_ev.ctx.input_sequence.data(), + static_cast(ctx.lmgen.codebook_count)}, + std::span{runtime_ev.ctx.audio_tokens.data(), + static_cast(ctx.lmgen.generated_dep_q)}, + runtime_ev.ctx.text_token, + }; + graph_step.sequence_id = ctx.session.sequence_id; + graph_step.error_out = &runtime_ev.ctx.graph_error; + runtime_ev.ctx.graph_accepted = + ctx.graph.dispatch_step(ctx.graph.executor, graph_step); + } +}; + +struct effect_advance_personaplex_prompt_pre_silence { + void operator()(const event::prefill_personaplex_prompt_run &, + context &ctx) const noexcept { + --ctx.voice.pre_text_silence_remaining; + ++ctx.lmgen.offset; + } +}; + +struct effect_advance_personaplex_prompt_text { + void operator()(const event::prefill_personaplex_prompt_run &, + context &ctx) const noexcept { + --ctx.voice.text_tokens_remaining; + ++ctx.lmgen.offset; + } +}; + +struct effect_advance_personaplex_prompt_post_silence { + void operator()(const event::prefill_personaplex_prompt_run &, + context &ctx) const noexcept { + --ctx.voice.post_text_silence_remaining; + ++ctx.lmgen.offset; + } +}; + +struct effect_finish_personaplex_prompt { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &ctx) const noexcept { + ctx.voice.prompt_ready = true; + runtime_ev.ctx.complete = true; + runtime_ev.ctx.remaining_frames = 0; + } +}; + +struct effect_publish_personaplex_prompt_pending { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const context &ctx) const noexcept { + runtime_ev.ctx.complete = false; + runtime_ev.ctx.remaining_frames = ctx.voice.pre_text_silence_remaining + + ctx.voice.text_tokens_remaining + + ctx.voice.post_text_silence_remaining; + } +}; + +struct effect_store_personaplex_prompt_complete_out { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &) const noexcept { + *runtime_ev.request.complete_out = runtime_ev.ctx.complete; + } +}; + +struct effect_store_personaplex_prompt_remaining_out { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &) const noexcept { + *runtime_ev.request.remaining_frames_out = runtime_ev.ctx.remaining_frames; + } +}; + +struct effect_store_voice_complete_out { + void operator()(const event::prefill_voice_run &runtime_ev, + context &) const noexcept { + *runtime_ev.request.complete_out = runtime_ev.ctx.complete; + } +}; + +struct effect_store_voice_remaining_out { + void operator()(const event::prefill_voice_run &runtime_ev, + context &) const noexcept { + *runtime_ev.request.remaining_frames_out = runtime_ev.ctx.remaining_frames; + } +}; + +struct effect_begin_step { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_accepted = false; + runtime_ev.ctx.provided_input = false; + runtime_ev.ctx.produced = false; + runtime_ev.ctx.text_token = 0; + runtime_ev.ctx.generated_dep_q = ctx.lmgen.generated_dep_q; + runtime_ev.ctx.delayed_dep_q = ctx.lmgen.delayed_dep_q; + runtime_ev.ctx.needed_tokens = ctx.lmgen.needed_tokens; + std::fill(runtime_ev.ctx.input_sequence.begin(), + runtime_ev.ctx.input_sequence.end(), k_token_ungenerated); + std::fill(runtime_ev.ctx.audio_tokens.begin(), + runtime_ev.ctx.audio_tokens.end(), k_token_ungenerated); + } +}; + +struct effect_write_full_input { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + for (int32_t index = 0; index < ctx.lmgen.codebook_count; ++index) { + const int32_t row = detail::cache_position( + ctx.lmgen, ctx.lmgen.offset + ctx.lmgen.delays[index]); + detail::cache_at(ctx.lmgen, row, index) = + runtime_ev.request.audio_tokens[static_cast(index)]; + } + runtime_ev.ctx.provided_input = true; + } +}; + +struct effect_write_tail_input { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t start = ctx.lmgen.delayed_dep_q + 1; + for (int32_t index = 0; index < ctx.lmgen.needed_tokens; ++index) { + const int32_t column = start + index; + const int32_t row = detail::cache_position( + ctx.lmgen, ctx.lmgen.offset + ctx.lmgen.delays[column]); + detail::cache_at(ctx.lmgen, row, column) = + runtime_ev.request.audio_tokens[static_cast(index)]; + } + } +}; + +struct effect_build_input_sequence { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset); + for (int32_t index = 0; index < ctx.lmgen.codebook_count; ++index) { + const bool use_initial = ctx.lmgen.offset <= ctx.lmgen.delays[index]; + const int32_t initial_lane = static_cast(use_initial); + const int32_t cache_lane = static_cast(!use_initial); + runtime_ev.ctx.input_sequence[static_cast(index)] = + (initial_lane * ctx.lmgen.initial[index]) + + (cache_lane * detail::cache_at(ctx.lmgen, row, index)); + } + } +}; + +struct effect_run_graph_runtime { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + event::graph_step graph_step{ + *ctx.session.model, + runtime_ev.ctx.memory_snapshot, + std::span{runtime_ev.ctx.input_sequence.data(), + static_cast(ctx.lmgen.codebook_count)}, + std::span{runtime_ev.ctx.audio_tokens.data(), + static_cast(ctx.lmgen.generated_dep_q)}, + runtime_ev.ctx.text_token, + }; + graph_step.sequence_id = ctx.session.sequence_id; + graph_step.error_out = &runtime_ev.ctx.graph_error; + runtime_ev.ctx.graph_accepted = + ctx.graph.dispatch_step(ctx.graph.executor, graph_step); + } +}; + +struct effect_store_graph_error_out { + template + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + *ev.request.graph_error_out = ev.ctx.graph_error; + } +}; + +struct effect_replace_audio_with_zero { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { + runtime_ev.ctx.audio_tokens[static_cast(index)] = k_token_zero; + } + } +}; + +struct effect_apply_delay_mask { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { + const int32_t delay_index = index + 1; + const bool masked = (ctx.lmgen.delay_steps > 0) && + (ctx.lmgen.offset < (ctx.lmgen.delays[delay_index] + + ctx.lmgen.delay_steps)); + const int32_t zero_lane = static_cast(masked); + const int32_t current_lane = static_cast(!masked); + runtime_ev.ctx.audio_tokens[static_cast(index)] = + (zero_lane * k_token_zero) + + (current_lane * + runtime_ev.ctx.audio_tokens[static_cast(index)]); + } + } +}; + +struct effect_advance_offset { + void operator()(const event::step_run &, context &ctx) const noexcept { + ++ctx.lmgen.offset; + } +}; + +struct effect_apply_delay_mask_and_advance { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + effect_apply_delay_mask{}(runtime_ev, ctx); + effect_advance_offset{}(runtime_ev, ctx); + } +}; + +struct effect_write_generated { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset); + detail::cache_at(ctx.lmgen, row, 0) = runtime_ev.ctx.text_token; + for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { + detail::cache_at(ctx.lmgen, row, index + 1) = + runtime_ev.ctx.audio_tokens[static_cast(index)]; + } + } +}; + +struct effect_write_generated_missing { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset); + detail::cache_at(ctx.lmgen, row, 0) = runtime_ev.ctx.text_token; + for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { + const int32_t column = index + 1; + const int32_t current = detail::cache_at(ctx.lmgen, row, column); + const int32_t missing_lane = + static_cast(current == k_token_ungenerated); + const int32_t current_lane = static_cast(!missing_lane); + detail::cache_at(ctx.lmgen, row, column) = + (current_lane * current) + + (missing_lane * + runtime_ev.ctx.audio_tokens[static_cast(index)]); + } + } +}; + +struct effect_consume_skip { + void operator()(const event::step_run &, context &ctx) const noexcept { + --ctx.lmgen.skip; + } +}; + +struct effect_collect_delayed_output { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset - + ctx.lmgen.max_delay + + ctx.lmgen.delays[0]); + runtime_ev.request.text_token_out = detail::cache_at(ctx.lmgen, row, 0); + for (int32_t index = 0; index < runtime_ev.ctx.delayed_dep_q; ++index) { + runtime_ev.request.audio_tokens_out[static_cast(index)] = + runtime_ev.ctx.audio_tokens[static_cast(index)]; + } + for (int32_t index = 1; index <= runtime_ev.ctx.delayed_dep_q; ++index) { + row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset - + ctx.lmgen.max_delay + + ctx.lmgen.delays[index]); + runtime_ev.request.audio_tokens_out[static_cast(index - 1)] = + detail::cache_at(ctx.lmgen, row, index); + } + } +}; + +struct effect_publish_output { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.produced = true; + } +}; + +struct effect_publish_no_output { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.produced = false; + } +}; + +struct effect_reset_session { + void operator()(const event::reset_run &, context &ctx) const noexcept { + ctx.session = {}; + ctx.voice = {}; + ctx.lmgen = {}; + } +}; + +template struct effect_store_error_out { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + *runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_store_produced_out { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + *runtime_ev.request.produced_out = runtime_ev.ctx.produced; + } +}; + +struct effect_emit_initialize_done { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.request.on_done(events::initialize_done{ + .request = &runtime_ev.request, + .n_q = ctx.session.n_q, + .dep_q = ctx.session.dep_q, + }); + } +}; + +struct effect_emit_initialize_error { + void operator()(const event::initialize_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_error(events::initialize_error{ + .request = &runtime_ev.request, + .err = runtime_ev.ctx.err, + }); + } +}; + +struct effect_emit_load_voice_done { + void operator()(const event::load_voice_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.request.on_done(events::load_voice_done{ + .request = &runtime_ev.request, + .prompt_frames = ctx.voice.prompt_frame_count, + }); + } +}; + +struct effect_emit_load_voice_error { + void operator()(const event::load_voice_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_error(events::load_voice_error{ + .request = &runtime_ev.request, + .err = runtime_ev.ctx.err, + }); + } +}; + +struct effect_emit_prefill_voice_done { + void operator()(const event::prefill_voice_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_done(events::prefill_voice_done{ + .request = &runtime_ev.request, + .complete = runtime_ev.ctx.complete, + .remaining_frames = runtime_ev.ctx.remaining_frames, + }); + } +}; + +struct effect_emit_prefill_voice_error { + void operator()(const event::prefill_voice_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_error(events::prefill_voice_error{ + .request = &runtime_ev.request, + .err = runtime_ev.ctx.err, + }); + } +}; + +struct effect_emit_begin_personaplex_prompt_done { + void operator()(const event::begin_personaplex_prompt_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_done(events::begin_personaplex_prompt_done{ + .request = &runtime_ev.request, + .remaining_frames = runtime_ev.ctx.remaining_frames, + }); + } +}; + +struct effect_emit_begin_personaplex_prompt_error { + void operator()(const event::begin_personaplex_prompt_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_error(events::begin_personaplex_prompt_error{ + .request = &runtime_ev.request, + .err = runtime_ev.ctx.err, + }); + } +}; + +struct effect_emit_prefill_personaplex_prompt_done { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_done(events::prefill_personaplex_prompt_done{ + .request = &runtime_ev.request, + .complete = runtime_ev.ctx.complete, + .remaining_frames = runtime_ev.ctx.remaining_frames, + }); + } +}; + +struct effect_emit_prefill_personaplex_prompt_error { + void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_error(events::prefill_personaplex_prompt_error{ + .request = &runtime_ev.request, + .err = runtime_ev.ctx.err, + }); + } +}; + +struct effect_emit_step_done { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.request.on_done(events::step_done{ + .request = &runtime_ev.request, + .produced = runtime_ev.ctx.produced, + }); + } +}; + +struct effect_emit_step_error { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.request.on_error(events::step_error{ + .request = &runtime_ev.request, + .err = runtime_ev.ctx.err, + }); + } +}; + +struct effect_mark_unexpected { + template + void operator()(const unexpected_event_type &ev, context &) const noexcept { + if constexpr (requires { ev.ctx.err; }) { + ev.ctx.err = detail_ns::to_error(error::unexpected_event); + } + } +}; + +struct effect_mark_unexpected_and_store { + template + void operator()(const unexpected_event_type &ev, + context &ctx) const noexcept { + effect_mark_unexpected{}(ev, ctx); + if constexpr (requires { + ev.ctx.err; + ev.request.error_out; + }) { + *ev.request.error_out = ev.ctx.err; + } + } +}; + +} // namespace emel::speech::generator::moshi::action diff --git a/src/emel/speech/generator/moshi/any.hpp b/src/emel/speech/generator/moshi/any.hpp new file mode 100644 index 00000000..67fa0047 --- /dev/null +++ b/src/emel/speech/generator/moshi/any.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "emel/speech/generator/moshi/sm.hpp" + +namespace emel::speech::generator::moshi { + +using MoshiGenerator = sm; + +} // namespace emel::speech::generator::moshi diff --git a/src/emel/speech/generator/moshi/context.hpp b/src/emel/speech/generator/moshi/context.hpp new file mode 100644 index 00000000..42409341 --- /dev/null +++ b/src/emel/speech/generator/moshi/context.hpp @@ -0,0 +1,90 @@ +#pragma once + +#include +#include + +#include "emel/memory/hybrid/context.hpp" +#include "emel/memory/hybrid/sm.hpp" +#include "emel/model/data.hpp" +#include "emel/model/moshi/detail.hpp" +#include "emel/speech/generator/moshi/events.hpp" + +namespace emel::speech::generator::moshi::action { + +inline constexpr int32_t k_max_codebooks = + static_cast(event::k_max_codebooks); +inline constexpr int32_t k_max_delay_rows = 128; +inline constexpr int32_t k_token_zero = -1; +inline constexpr int32_t k_token_ungenerated = -2; + +using graph_step_dispatch_fn = bool(void *, const event::graph_step &); + +struct graph_binding { + void *executor = nullptr; + graph_step_dispatch_fn *dispatch_step = nullptr; +}; + +struct lmgen_state { + int32_t codebook_count = 0; + int32_t generated_dep_q = 0; + int32_t delayed_dep_q = 0; + int32_t needed_tokens = 0; + int32_t max_delay = 0; + int32_t delay_steps = 0; + int32_t cache_row_count = 0; + int64_t offset = 0; + int32_t skip = 0; + std::array delays = {}; + std::array initial = {}; + std::array cache = {}; +}; + +struct runtime { + const emel::model::data *model = nullptr; + emel::model::moshi::detail::execution_contract contract = {}; + int32_t n_q = 0; + int32_t dep_q = 0; + int32_t text_card = 0; + int32_t audio_card = 0; + int32_t sequence_id = 0; +}; + +struct voice_prompt_state { + const emel::model::data *model = nullptr; + emel::model::moshi::detail::execution_contract contract = {}; + int32_t embedding_dim = 0; + int32_t prompt_frame_count = 0; + int32_t prompt_frame_index = 0; + int32_t cache_row_count = 0; + int32_t cache_column_count = 0; + int32_t pre_text_silence_remaining = 0; + int32_t text_tokens_remaining = 0; + int32_t post_text_silence_remaining = 0; + bool loaded = false; + bool ready = false; + bool prompt_started = false; + bool prompt_ready = false; +}; + +struct context { + context() = default; + explicit context(const emel::memory::hybrid::kv_binding &kv_cache) + : memory(kv_cache) {} + context(const emel::memory::hybrid::kv_binding &kv_cache, + const graph_binding &graph_executor) + : graph(graph_executor), memory(kv_cache) {} + + runtime session = {}; + voice_prompt_state voice = {}; + graph_binding graph = {}; + lmgen_state lmgen = {}; + emel::memory::hybrid::sm memory = {}; +}; + +inline graph_binding +bind_graph_executor(void *executor, + graph_step_dispatch_fn &dispatch_step) noexcept { + return graph_binding{.executor = executor, .dispatch_step = &dispatch_step}; +} + +} // namespace emel::speech::generator::moshi::action diff --git a/src/emel/speech/generator/moshi/detail.hpp b/src/emel/speech/generator/moshi/detail.hpp new file mode 100644 index 00000000..29acbcb8 --- /dev/null +++ b/src/emel/speech/generator/moshi/detail.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include "emel/speech/generator/moshi/context.hpp" + +namespace emel::speech::generator::moshi::detail { + +template +constexpr decltype(auto) +unwrap_runtime_event(const runtime_event_type &ev) noexcept { + if constexpr (requires { ev.event_; }) { + return (ev.event_); + } else { + return (ev); + } +} + +inline int32_t cache_position(const action::lmgen_state &lmgen, + const int64_t offset) noexcept { + const int64_t row_count = lmgen.cache_row_count; + const int64_t position = offset % row_count; + return static_cast(position + ((position < 0) * row_count)); +} + +inline int32_t &cache_at(action::lmgen_state &lmgen, const int32_t row, + const int32_t column) noexcept { + return lmgen + .cache[static_cast(row * action::k_max_codebooks + column)]; +} + +inline int32_t cache_at(const action::lmgen_state &lmgen, const int32_t row, + const int32_t column) noexcept { + return lmgen + .cache[static_cast(row * action::k_max_codebooks + column)]; +} + +} // namespace emel::speech::generator::moshi::detail diff --git a/src/emel/speech/generator/moshi/errors.hpp b/src/emel/speech/generator/moshi/errors.hpp new file mode 100644 index 00000000..1a4fcb3b --- /dev/null +++ b/src/emel/speech/generator/moshi/errors.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "emel/error/error.hpp" + +namespace emel::speech::generator::moshi { + +enum class error : emel::error::type { + none = 0, + not_initialized = 1, + bind_failed = 2, + memory = 3, + request_shape = 4, + graph_runtime_unavailable = 5, + graph_runtime = 6, + output_waiting = 7, + voice_contract = 8, + voice_prompt_pending = 9, + personaplex_prompt = 10, + unexpected_event = 11, +}; + +} // namespace emel::speech::generator::moshi diff --git a/src/emel/speech/generator/moshi/events.hpp b/src/emel/speech/generator/moshi/events.hpp new file mode 100644 index 00000000..8b9ea92e --- /dev/null +++ b/src/emel/speech/generator/moshi/events.hpp @@ -0,0 +1,311 @@ +#pragma once + +#include +#include +#include +#include + +#include "emel/callback.hpp" +#include "emel/error/error.hpp" +#include "emel/memory/view.hpp" +#include "emel/model/data.hpp" +#include "emel/speech/generator/moshi/errors.hpp" + +namespace emel::speech::generator::moshi::events { + +struct initialize_done; +struct initialize_error; +struct load_voice_done; +struct load_voice_error; +struct begin_personaplex_prompt_done; +struct begin_personaplex_prompt_error; +struct prefill_voice_done; +struct prefill_voice_error; +struct prefill_personaplex_prompt_done; +struct prefill_personaplex_prompt_error; +struct step_done; +struct step_error; + +} // namespace emel::speech::generator::moshi::events + +namespace emel::speech::generator::moshi::event { + +inline constexpr std::size_t k_max_codebooks = 64; +inline constexpr std::size_t k_max_voice_embedding_dim = 8192; + +struct initialize { + explicit initialize(const emel::model::data &model_ref) noexcept + : model(model_ref) {} + + const emel::model::data &model; + int32_t max_sequences = 1; + int32_t max_blocks = 4096; + int32_t block_tokens = emel::memory::view::DEFAULT_BLOCK_TOKENS; + int32_t sequence_id = 0; + emel::error::type *error_out = nullptr; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct load_voice { + explicit load_voice(const emel::model::data &voice_model_ref) noexcept + : voice_model(voice_model_ref) {} + + const emel::model::data &voice_model; + emel::error::type *error_out = nullptr; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct begin_personaplex_prompt { + int32_t text_token_count = 0; + int32_t pre_text_silence_frames = 0; + int32_t post_text_silence_frames = 0; + emel::error::type *error_out = nullptr; + emel::callback on_done = + {}; + emel::callback + on_error = {}; +}; + +struct prefill_voice { + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; + bool *complete_out = nullptr; + int32_t *remaining_frames_out = nullptr; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct prefill_personaplex_prompt { + int32_t text_token = -1; + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; + bool *complete_out = nullptr; + int32_t *remaining_frames_out = nullptr; + emel::callback + on_done = {}; + emel::callback + on_error = {}; +}; + +struct step { + step(std::span audio_tokens_ref, + std::span audio_tokens_out_ref, + int32_t &text_token_out_ref) noexcept + : audio_tokens(audio_tokens_ref), audio_tokens_out(audio_tokens_out_ref), + text_token_out(text_token_out_ref) {} + + std::span audio_tokens = {}; + std::span audio_tokens_out = {}; + int32_t &text_token_out; + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; + bool *produced_out = nullptr; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct reset {}; + +struct graph_step { + graph_step(const emel::model::data &model_ref, + const emel::memory::view::snapshot &memory_snapshot_ref, + std::span input_sequence_ref, + std::span audio_tokens_out_ref, + int32_t &text_token_out_ref) noexcept + : model(model_ref), memory_snapshot(memory_snapshot_ref), + input_sequence(input_sequence_ref), + audio_tokens_out(audio_tokens_out_ref), + text_token_out(text_token_out_ref) {} + + const emel::model::data &model; + const emel::memory::view::snapshot &memory_snapshot; + int32_t sequence_id = 0; + std::span input_sequence = {}; + std::span input_embedding = {}; + int32_t forced_text_token = -1; + std::span audio_tokens_out = {}; + int32_t &text_token_out; + emel::error::type *error_out = nullptr; +}; + +struct initialize_ctx { + emel::error::type err = emel::error::cast(error::none); + bool memory_accepted = false; + int32_t memory_error = static_cast(emel::error::cast(error::none)); +}; + +struct load_voice_ctx { + emel::error::type err = emel::error::cast(error::none); +}; + +struct begin_personaplex_prompt_ctx { + emel::error::type err = emel::error::cast(error::none); + int32_t remaining_frames = 0; +}; + +struct prefill_voice_ctx { + explicit prefill_voice_ctx( + emel::memory::view::snapshot &memory_snapshot_ref) noexcept + : memory_snapshot(memory_snapshot_ref) {} + + emel::error::type err = emel::error::cast(error::none); + bool memory_accepted = false; + int32_t memory_error = static_cast(emel::error::cast(error::none)); + int32_t memory_block_count = 0; + bool embedding_frame_ok = false; + bool graph_accepted = false; + emel::error::type graph_error = emel::error::cast(error::none); + bool complete = false; + int32_t remaining_frames = 0; + int32_t text_token = 0; + std::array embedding_frame = {}; + std::array input_sequence = {}; + std::array audio_tokens = {}; + emel::memory::view::snapshot &memory_snapshot; +}; + +struct prefill_personaplex_prompt_ctx { + explicit prefill_personaplex_prompt_ctx( + emel::memory::view::snapshot &memory_snapshot_ref) noexcept + : memory_snapshot(memory_snapshot_ref) {} + + emel::error::type err = emel::error::cast(error::none); + bool memory_accepted = false; + int32_t memory_error = static_cast(emel::error::cast(error::none)); + int32_t memory_block_count = 0; + bool graph_accepted = false; + emel::error::type graph_error = emel::error::cast(error::none); + bool complete = false; + int32_t remaining_frames = 0; + int32_t text_token = 0; + std::array prompt_sequence = {}; + std::array input_sequence = {}; + std::array audio_tokens = {}; + emel::memory::view::snapshot &memory_snapshot; +}; + +struct step_ctx { + explicit step_ctx(emel::memory::view::snapshot &memory_snapshot_ref) noexcept + : memory_snapshot(memory_snapshot_ref) {} + + emel::error::type err = emel::error::cast(error::none); + bool memory_accepted = false; + int32_t memory_error = static_cast(emel::error::cast(error::none)); + int32_t memory_block_count = 0; + bool graph_accepted = false; + emel::error::type graph_error = emel::error::cast(error::none); + bool provided_input = false; + bool produced = false; + int32_t text_token = 0; + int32_t generated_dep_q = 0; + int32_t delayed_dep_q = 0; + int32_t needed_tokens = 0; + std::array input_sequence = {}; + std::array audio_tokens = {}; + emel::memory::view::snapshot &memory_snapshot; +}; + +struct initialize_run { + const initialize &request; + initialize_ctx &ctx; +}; + +struct load_voice_run { + const load_voice &request; + load_voice_ctx &ctx; +}; + +struct begin_personaplex_prompt_run { + const begin_personaplex_prompt &request; + begin_personaplex_prompt_ctx &ctx; +}; + +struct prefill_voice_run { + const prefill_voice &request; + prefill_voice_ctx &ctx; +}; + +struct prefill_personaplex_prompt_run { + const prefill_personaplex_prompt &request; + prefill_personaplex_prompt_ctx &ctx; +}; + +struct step_run { + const step &request; + step_ctx &ctx; +}; + +struct reset_run { + const reset &request; +}; + +} // namespace emel::speech::generator::moshi::event + +namespace emel::speech::generator::moshi::events { + +struct initialize_done { + const event::initialize *request = nullptr; + int32_t n_q = 0; + int32_t dep_q = 0; +}; + +struct initialize_error { + const event::initialize *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +struct load_voice_done { + const event::load_voice *request = nullptr; + int32_t prompt_frames = 0; +}; + +struct load_voice_error { + const event::load_voice *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +struct begin_personaplex_prompt_done { + const event::begin_personaplex_prompt *request = nullptr; + int32_t remaining_frames = 0; +}; + +struct begin_personaplex_prompt_error { + const event::begin_personaplex_prompt *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +struct prefill_voice_done { + const event::prefill_voice *request = nullptr; + bool complete = false; + int32_t remaining_frames = 0; +}; + +struct prefill_voice_error { + const event::prefill_voice *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +struct prefill_personaplex_prompt_done { + const event::prefill_personaplex_prompt *request = nullptr; + bool complete = false; + int32_t remaining_frames = 0; +}; + +struct prefill_personaplex_prompt_error { + const event::prefill_personaplex_prompt *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +struct step_done { + const event::step *request = nullptr; + bool produced = false; +}; + +struct step_error { + const event::step *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +} // namespace emel::speech::generator::moshi::events diff --git a/src/emel/speech/generator/moshi/executor/actions.hpp b/src/emel/speech/generator/moshi/executor/actions.hpp new file mode 100644 index 00000000..78b628a9 --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/actions.hpp @@ -0,0 +1,1864 @@ +#pragma once + +#include "emel/model/moshi/detail.hpp" +#include "emel/speech/generator/moshi/executor/context.hpp" +#include "emel/speech/generator/moshi/executor/detail.hpp" +#include "emel/speech/generator/moshi/executor/events.hpp" + +#include +#include +#include +#include +#include + +namespace emel::speech::generator::moshi::executor::action { + +namespace detail_ns { + +inline emel::error::type to_error(const error value) noexcept { + return emel::error::cast(value); +} + +} // namespace detail_ns + +namespace sampling_ns { + +inline int32_t bounded_top_k(const int32_t requested, + const int32_t card) noexcept { + int32_t top_k = requested; + if (top_k > card) { + top_k = card; + } + if (top_k < 0) { + top_k = 0; + } + return top_k; +} + +inline void reset_top_k(event::step_ctx &ctx, const int32_t top_k) noexcept { + for (int32_t slot = 0; slot < top_k; ++slot) { + ctx.top_scores[static_cast(slot)] = + -std::numeric_limits::infinity(); + ctx.top_indices[static_cast(slot)] = -1; + } +} + +inline void insert_top_k(event::step_ctx &ctx, const int32_t top_k, + const int32_t index, const float score) noexcept { + for (int32_t slot = 0; slot < top_k; ++slot) { + if (score > ctx.top_scores[static_cast(slot)]) { + for (int32_t move = top_k - 1; move > slot; --move) { + ctx.top_scores[static_cast(move)] = + ctx.top_scores[static_cast(move - 1)]; + ctx.top_indices[static_cast(move)] = + ctx.top_indices[static_cast(move - 1)]; + } + ctx.top_scores[static_cast(slot)] = score; + ctx.top_indices[static_cast(slot)] = index; + return; + } + } +} + +inline bool +consume_reference_random_draws(const int32_t card, + const int32_t requested_top_k) noexcept { + const int32_t top_k = bounded_top_k(requested_top_k, card); + if (card <= 0 || top_k <= 0 || + static_cast(top_k) > detail::k_max_sampling_top_k) { + return false; + } + for (int32_t index = 0; index < top_k; ++index) { + (void)std::rand(); + } + return true; +} + +inline bool sample_top_k_exponential(event::step_ctx &ctx, const int32_t card, + const int32_t requested_top_k, + const float temperature) noexcept { + const int32_t top_k = bounded_top_k(requested_top_k, card); + if (card <= 0 || temperature <= 0.0f || top_k <= 0 || + static_cast(card) > detail::k_max_sampling_card || + static_cast(top_k) > detail::k_max_sampling_top_k) { + ctx.best_index = -1; + ctx.best_score = 0.0f; + return false; + } + + reset_top_k(ctx, top_k); + for (int32_t index = 0; index < card; ++index) { + insert_top_k(ctx, top_k, index, ctx.logits[static_cast(index)]); + } + + const float max_score = ctx.top_scores[0]; + float best_q = -std::numeric_limits::infinity(); + int32_t best_index = -1; + for (int32_t slot = 0; slot < top_k; ++slot) { + const float uniform = + static_cast(std::rand()) / static_cast(RAND_MAX); + const float exponential = -std::log(uniform); + const float weight = std::exp( + (ctx.top_scores[static_cast(slot)] - max_score) / temperature); + const float q = weight / exponential; + if (q > best_q) { + best_q = q; + best_index = ctx.top_indices[static_cast(slot)]; + } + } + + ctx.best_index = best_index; + ctx.best_score = best_q; + return best_index >= 0; +} + +} // namespace sampling_ns + +struct effect_bind_contract { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.session = {}; + ctx.sampling = {}; + ctx.session.model = &runtime_ev.request.model; + ctx.session.codebook_count = runtime_ev.request.model.moshi_lm.n_q + 1; + ctx.session.dep_q = runtime_ev.request.model.moshi_lm.dep_q; + ctx.session.text_card = runtime_ev.request.model.moshi_lm.text_card; + ctx.session.audio_card = runtime_ev.request.model.moshi_lm.card; + ctx.session.hidden_dim = runtime_ev.request.model.moshi_lm.dim; + ctx.sampling.enabled = runtime_ev.request.sampling_enabled; + ctx.sampling.consume_forced_text = + runtime_ev.request.sampling_consume_forced_text; + ctx.sampling.audio_temperature = + runtime_ev.request.sampling_audio_temperature; + ctx.sampling.text_temperature = + runtime_ev.request.sampling_text_temperature; + ctx.sampling.audio_top_k = runtime_ev.request.sampling_audio_top_k; + ctx.sampling.text_top_k = runtime_ev.request.sampling_text_top_k; + ctx.sampling.seed = runtime_ev.request.sampling_seed; + std::srand(static_cast(ctx.sampling.seed)); + (void)emel::model::moshi::detail::build_execution_contract( + runtime_ev.request.model, ctx.session.contract); + } +}; + +struct effect_mark_bind_failed { + void operator()(const event::initialize_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::bind_failed); + } +}; + +struct effect_mark_not_initialized { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::not_initialized); + } +}; + +struct effect_mark_model_mismatch { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::model_mismatch); + } +}; + +struct effect_mark_request_shape { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::request_shape); + } +}; + +struct effect_mark_graph_execution_unsupported { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.err = + detail_ns::to_error(error::graph_execution_unsupported); + } +}; + +struct effect_begin_input_embedding { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + (void)model; + runtime_ev.ctx.input_embedding_ok = false; + runtime_ev.ctx.input_text_embedding_ok = false; + runtime_ev.ctx.input_audio_embedding_ok = false; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.depformer_input_projection_bound = false; + runtime_ev.ctx.depformer_input_projection_ok = false; + runtime_ev.ctx.temporal_layer_norm_rms_ok = false; + runtime_ev.ctx.temporal_layer_norm_ok = false; + runtime_ev.ctx.temporal_layer_projection_ok = false; + runtime_ev.ctx.temporal_layer_rope_ok = false; + runtime_ev.ctx.temporal_layer_cache_write_ok = false; + runtime_ev.ctx.temporal_layer_attention_ok = false; + runtime_ev.ctx.temporal_layer_out_projection_ok = false; + runtime_ev.ctx.temporal_layer_residual_ok = false; + runtime_ev.ctx.temporal_layer_norm2_rms_ok = false; + runtime_ev.ctx.temporal_layer_norm2_ok = false; + runtime_ev.ctx.temporal_layer_gating_in_ok = false; + runtime_ev.ctx.temporal_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.temporal_layer_silu_gate_ok = false; + runtime_ev.ctx.temporal_layer_gating_out_ok = false; + runtime_ev.ctx.temporal_layer_ff_residual_ok = false; + runtime_ev.ctx.temporal_out_norm_rms_ok = false; + runtime_ev.ctx.temporal_out_norm_ok = false; + runtime_ev.ctx.text_logits_ok = false; + runtime_ev.ctx.text_sampling_ok = false; + runtime_ev.ctx.depformer_kv_bound = false; + runtime_ev.ctx.depformer_input_ok = false; + runtime_ev.ctx.depformer_layer_norm_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm_ok = false; + runtime_ev.ctx.depformer_layer_projection_ok = false; + runtime_ev.ctx.depformer_layer_cache_write_ok = false; + runtime_ev.ctx.depformer_layer_attention_ok = false; + runtime_ev.ctx.depformer_layer_out_projection_ok = false; + runtime_ev.ctx.depformer_layer_residual_ok = false; + runtime_ev.ctx.depformer_layer_norm2_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm2_ok = false; + runtime_ev.ctx.depformer_layer_gating_in_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_ok = false; + runtime_ev.ctx.depformer_layer_gating_out_ok = false; + runtime_ev.ctx.depformer_layer_ff_residual_ok = false; + runtime_ev.ctx.depformer_logits_ok = false; + runtime_ev.ctx.depformer_sampling_ok = false; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + runtime_ev.ctx.input_audio_codebook_index = 0; + runtime_ev.ctx.temporal_layer_index = 0; + runtime_ev.ctx.temporal_logical_position = -1; + runtime_ev.ctx.temporal_physical_position = -1; + runtime_ev.ctx.depformer_codebook_index = 0; + runtime_ev.ctx.depformer_weight_index = -1; + runtime_ev.ctx.depformer_layer_index = 0; + runtime_ev.ctx.depformer_logical_position = -1; + runtime_ev.ctx.depformer_physical_position = -1; + runtime_ev.ctx.depformer_valid_positions = 0; + runtime_ev.ctx.embedding_dim = 0; + runtime_ev.ctx.embedding_view = {}; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.hidden.data(), static_cast(hidden_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.transformer_out.data(), + static_cast(hidden_dim), 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim), 0.0f); + std::fill_n(runtime_ev.ctx.qkv.data(), static_cast(hidden_dim) * 3u, + 0.0f); + std::fill_n(runtime_ev.ctx.attention.data(), + static_cast(hidden_dim), 0.0f); + std::fill_n(runtime_ev.ctx.projection.data(), + static_cast(hidden_dim), 0.0f); + std::fill(runtime_ev.ctx.gating_projection.begin(), + runtime_ev.ctx.gating_projection.end(), 0.0f); + std::fill(runtime_ev.ctx.gating_silu.begin(), + runtime_ev.ctx.gating_silu.end(), 0.0f); + std::fill(runtime_ev.ctx.gated.begin(), runtime_ev.ctx.gated.end(), 0.0f); + } +}; + +struct effect_use_depformer_scheduled_weight { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + runtime_ev.ctx.depformer_weight_index = + lm.depformer_weight_schedule[static_cast(codebook)]; + } +}; + +struct effect_use_depformer_codebook_weight { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + runtime_ev.ctx.depformer_weight_index = + runtime_ev.ctx.depformer_codebook_index; + } +}; + +struct effect_apply_external_input_embedding { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.input_embedding_ok = false; + for (int32_t index = 0; index < hidden_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] = + runtime_ev.request.input_embedding[static_cast(index)]; + } + runtime_ev.ctx.input_embedding_ok = true; + } +}; + +struct effect_bind_input_text_embedding { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const auto *text_emb = + detail::find_tensor(runtime_ev.request.model, "lm.text_emb.weight"); + runtime_ev.ctx.embedding_view = {}; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.embedding_dim = ctx.session.hidden_dim; + runtime_ev.ctx.row_index = runtime_ev.request.input_sequence[0]; + runtime_ev.ctx.input_text_embedding_ok = false; + runtime_ev.ctx.embedding_view_bound = + detail::bind_tensor_view(*text_emb, runtime_ev.ctx.embedding_view); + } +}; + +struct effect_run_embedding_row_fetch { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t embedding_dim = runtime_ev.ctx.embedding_dim; + runtime_ev.ctx.embedding_row_ok = false; + std::fill_n(runtime_ev.ctx.row.data(), static_cast(embedding_dim), + 0.0f); + emel::kernel::event::op_get_rows rows_ev{ + .src0 = runtime_ev.ctx.embedding_view, + .src1 = detail::make_i32_src(&runtime_ev.ctx.row_index, 1u), + .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), + static_cast(embedding_dim)), + }; + runtime_ev.ctx.embedding_row_ok = ctx.kernel.process_event(rows_ev); + } +}; + +struct effect_apply_input_text_embedding_row { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const int32_t embedding_dim = runtime_ev.ctx.embedding_dim; + runtime_ev.ctx.input_text_embedding_ok = false; + for (int32_t index = 0; index < embedding_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] += + runtime_ev.ctx.row[static_cast(index)]; + } + runtime_ev.ctx.input_text_embedding_ok = true; + } +}; + +struct effect_bind_input_audio_embedding { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const int32_t index = runtime_ev.ctx.input_audio_codebook_index; + const auto *audio_emb = detail::find_indexed_tensor( + runtime_ev.request.model, "lm.emb.%d.weight", index); + runtime_ev.ctx.embedding_view = {}; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.embedding_dim = ctx.session.hidden_dim; + runtime_ev.ctx.row_index = + runtime_ev.request.input_sequence[static_cast(index + 1)]; + runtime_ev.ctx.input_audio_embedding_ok = false; + runtime_ev.ctx.embedding_view_bound = + detail::bind_tensor_view(*audio_emb, runtime_ev.ctx.embedding_view); + } +}; + +struct effect_apply_input_audio_embedding_row { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const int32_t embedding_dim = runtime_ev.ctx.embedding_dim; + runtime_ev.ctx.input_audio_embedding_ok = false; + for (int32_t index = 0; index < embedding_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] += + runtime_ev.ctx.row[static_cast(index)]; + } + runtime_ev.ctx.input_audio_embedding_ok = true; + } +}; + +struct effect_skip_zero_input_audio_embedding { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.input_audio_embedding_ok = true; + } +}; + +struct effect_advance_input_audio_codebook { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + ++runtime_ev.ctx.input_audio_codebook_index; + runtime_ev.ctx.input_audio_embedding_ok = false; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.embedding_dim = 0; + runtime_ev.ctx.embedding_view = {}; + } +}; + +struct effect_finish_input_embedding { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.input_embedding_ok = true; + } +}; + +struct effect_run_temporal_layer_norm_rms { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_layer_norm_rms_ok = false; + runtime_ev.ctx.temporal_layer_norm_ok = false; + + std::fill_n(runtime_ev.ctx.row.data(), static_cast(hidden_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim), 0.0f); + + emel::kernel::event::op_rms_norm rms_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.hidden.data(), + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), + static_cast(hidden_dim)), + }; + detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + runtime_ev.ctx.temporal_layer_norm_rms_ok = + ctx.kernel.process_event(rms_ev); + } +}; + +struct effect_run_temporal_layer_norm_scale { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + runtime_ev.ctx.temporal_layer_norm_ok = false; + + const auto *norm1 = + detail::find_lm_transformer_tensor(model, layer, "norm1.alpha"); + const auto *alpha = static_cast(norm1->data); + + emel::kernel::event::op_mul mul_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.row.data(), + static_cast(hidden_dim)), + .src1 = detail::make_f32_src(alpha, static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim)), + }; + runtime_ev.ctx.temporal_layer_norm_ok = ctx.kernel.process_event(mul_ev); + } +}; + +struct effect_bind_temporal_layer_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + runtime_ev.ctx.temporal_layer_projection_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.qkv.data(), static_cast(hidden_dim) * 3u, + 0.0f); + + const auto *projection = + detail::find_lm_transformer_projection(model, layer); + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_temporal_layer_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_layer_projection_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.qkv.data(), 1u, + static_cast(hidden_dim) * 3u), + }; + runtime_ev.ctx.temporal_layer_projection_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_apply_temporal_layer_rope { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t head_dim = hidden_dim / lm.num_heads; + const int32_t half = head_dim / 2; + runtime_ev.ctx.temporal_layer_rope_ok = false; + runtime_ev.ctx.temporal_logical_position = detail::current_logical_position( + runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id); + runtime_ev.ctx.temporal_physical_position = detail::physical_position( + runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, + runtime_ev.ctx.temporal_logical_position); + + const float neg_log_period = -std::log(static_cast(lm.max_period)); + const float position = + static_cast(runtime_ev.ctx.temporal_logical_position); + for (int32_t part = 0; part < 2; ++part) { + float *data = runtime_ev.ctx.qkv.data() + + static_cast(part) * static_cast(hidden_dim); + for (int32_t head = 0; head < lm.num_heads; ++head) { + float *head_data = + data + static_cast(head) * static_cast(head_dim); + for (int32_t index = 0; index < half; ++index) { + const float freq = + std::exp(neg_log_period * static_cast(index) / + static_cast(half)); + const float arg = position * freq; + const float rotr = std::cos(arg); + const float roti = std::sin(arg); + const float real = head_data[static_cast(2 * index)]; + const float imag = head_data[static_cast(2 * index + 1)]; + runtime_ev.ctx.rope[static_cast(index)] = + real * rotr - imag * roti; + runtime_ev.ctx.rope[static_cast(half + index)] = + real * roti + imag * rotr; + } + std::memcpy(head_data, runtime_ev.ctx.rope.data(), + static_cast(head_dim) * sizeof(float)); + } + } + runtime_ev.ctx.temporal_layer_rope_ok = true; + } +}; + +struct effect_write_temporal_layer_kv_cache { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_layer_cache_write_ok = false; + auto &view = runtime_ev.ctx.temporal_kv; + const size_t layer_offset = view.layer_cache_offsets[static_cast( + runtime_ev.ctx.temporal_layer_index)]; + const size_t physical_position = + static_cast(runtime_ev.ctx.temporal_physical_position); + const size_t dim = static_cast(hidden_dim); + const size_t begin = layer_offset + physical_position * dim; + const float *key = runtime_ev.ctx.qkv.data() + dim; + const float *value = runtime_ev.ctx.qkv.data() + dim * 2u; + + for (size_t index = 0; index < dim; ++index) { + view.key_cache[begin + index] = + emel::kernel::detail::fp32_to_bf16(key[index]); + view.value_cache[begin + index] = + emel::kernel::detail::fp32_to_bf16(value[index]); + } + runtime_ev.ctx.temporal_layer_cache_write_ok = true; + } +}; + +struct effect_run_temporal_layer_attention { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const auto &snapshot = runtime_ev.request.memory_snapshot; + const auto &view = runtime_ev.ctx.temporal_kv; + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t head_dim = hidden_dim / lm.num_heads; + const int32_t capacity = view.position_capacity; + const int32_t sequence_length = + snapshot.sequence_length(runtime_ev.request.sequence_id); + const int32_t current_logical = runtime_ev.ctx.temporal_logical_position; + const int32_t logical_begin = + sequence_length > capacity ? sequence_length - capacity : 0; + const float scale = 1.0f / std::sqrt(static_cast(head_dim)); + const size_t layer_offset = view.layer_cache_offsets[static_cast( + runtime_ev.ctx.temporal_layer_index)]; + runtime_ev.ctx.temporal_layer_attention_ok = false; + std::fill_n(runtime_ev.ctx.attention.data(), + static_cast(hidden_dim), 0.0f); + + for (int32_t head = 0; head < lm.num_heads; ++head) { + const int32_t head_offset = head * head_dim; + const float *q_head = + runtime_ev.ctx.qkv.data() + static_cast(head_offset); + for (int32_t dim = 0; dim < head_dim; ++dim) { + runtime_ev.ctx.q_bf16[static_cast(dim)] = + emel::kernel::detail::fp32_to_bf16(q_head[dim]); + } + for (int32_t physical = 0; physical < capacity; ++physical) { + runtime_ev.ctx.attention_scores[static_cast(physical)] = + -std::numeric_limits::infinity(); + } + for (int32_t logical = logical_begin; logical < sequence_length; + ++logical) { + const int32_t physical = detail::physical_position( + snapshot, runtime_ev.request.sequence_id, logical); + const int32_t delta = current_logical - logical; + const bool visible = + delta >= 0 && (lm.context <= 0 || delta < lm.context); + const size_t cache_begin = + layer_offset + + static_cast(physical) * static_cast(hidden_dim) + + static_cast(head_offset); + runtime_ev.ctx.attention_scores[static_cast(physical)] = + visible ? emel::kernel::detail::vec_dot_bf16_ggml( + head_dim, view.key_cache.data() + cache_begin, + runtime_ev.ctx.q_bf16.data()) * + scale + : -std::numeric_limits::infinity(); + } + + emel::kernel::detail::soft_max_row_ggml( + capacity, runtime_ev.ctx.attention_scores.data()); + for (int32_t physical = 0; physical < capacity; ++physical) { + runtime_ev.ctx.attention_weights_bf16[static_cast(physical)] = + emel::kernel::detail::fp32_to_bf16( + runtime_ev.ctx.attention_scores[static_cast(physical)]); + } + + float *attention_head = + runtime_ev.ctx.attention.data() + static_cast(head_offset); + for (int32_t dim = 0; dim < head_dim; ++dim) { + double sum = 0.0; + for (int32_t logical = logical_begin; logical < sequence_length; + ++logical) { + const int32_t physical = detail::physical_position( + snapshot, runtime_ev.request.sequence_id, logical); + const size_t value_index = + layer_offset + + static_cast(physical) * static_cast(hidden_dim) + + static_cast(head_offset + dim); + sum += + static_cast( + emel::kernel::detail::bf16_to_fp32( + view.value_cache[value_index]) * + emel::kernel::detail::bf16_to_fp32( + runtime_ev.ctx.attention_weights_bf16[static_cast( + physical)])); + } + attention_head[dim] = static_cast(sum); + } + } + runtime_ev.ctx.temporal_layer_attention_ok = true; + } +}; + +struct effect_bind_temporal_layer_out_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + runtime_ev.ctx.temporal_layer_out_projection_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.projection.data(), + static_cast(hidden_dim), 0.0f); + + const auto *projection = detail::find_lm_transformer_tensor( + model, layer, "self_attn.out_projs.0.weight"); + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_temporal_layer_out_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_layer_out_projection_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.attention.data(), 1u, + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.projection.data(), 1u, + static_cast(hidden_dim)), + }; + runtime_ev.ctx.temporal_layer_out_projection_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_apply_temporal_layer_attention_residual { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_layer_residual_ok = false; + for (int32_t index = 0; index < hidden_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] += + runtime_ev.ctx.projection[static_cast(index)]; + } + runtime_ev.ctx.temporal_layer_residual_ok = true; + } +}; + +struct effect_run_temporal_layer_norm2_rms { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_layer_norm2_rms_ok = false; + runtime_ev.ctx.temporal_layer_norm2_ok = false; + + std::fill_n(runtime_ev.ctx.row.data(), static_cast(hidden_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim), 0.0f); + + emel::kernel::event::op_rms_norm rms_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.hidden.data(), + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), + static_cast(hidden_dim)), + }; + detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + runtime_ev.ctx.temporal_layer_norm2_rms_ok = + ctx.kernel.process_event(rms_ev); + } +}; + +struct effect_run_temporal_layer_norm2_scale { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + runtime_ev.ctx.temporal_layer_norm2_ok = false; + + const auto *norm2 = + detail::find_lm_transformer_tensor(model, layer, "norm2.alpha"); + const auto *alpha = static_cast(norm2->data); + + emel::kernel::event::op_mul mul_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.row.data(), + static_cast(hidden_dim)), + .src1 = detail::make_f32_src(alpha, static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim)), + }; + runtime_ev.ctx.temporal_layer_norm2_ok = ctx.kernel.process_event(mul_ev); + } +}; + +struct effect_bind_temporal_layer_gating_in { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + (void)ctx; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *linear_in = detail::find_lm_transformer_tensor( + model, layer, "gating.linear_in.weight"); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + runtime_ev.ctx.temporal_layer_gating_in_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.gating_projection.data(), + static_cast(projection_dim), 0.0f); + + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*linear_in, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_temporal_layer_gating_in { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *linear_in = detail::find_lm_transformer_tensor( + model, layer, "gating.linear_in.weight"); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + runtime_ev.ctx.temporal_layer_gating_in_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.gating_projection.data(), 1u, + projection_dim), + }; + runtime_ev.ctx.temporal_layer_gating_in_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_run_temporal_layer_silu_gate_silu { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto *linear_in = detail::find_lm_transformer_tensor( + runtime_ev.request.model, runtime_ev.ctx.temporal_layer_index, + "gating.linear_in.weight"); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + const uint64_t gate_dim = projection_dim / 2u; + runtime_ev.ctx.temporal_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.temporal_layer_silu_gate_ok = false; + std::fill_n(runtime_ev.ctx.gating_silu.data(), + static_cast(gate_dim), 0.0f); + std::fill_n(runtime_ev.ctx.gated.data(), static_cast(gate_dim), + 0.0f); + + emel::kernel::event::op_unary silu_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.gating_projection.data(), + gate_dim), + .dst = + detail::make_f32_dst(runtime_ev.ctx.gating_silu.data(), gate_dim), + .subop = emel::kernel::event::unary_subop::silu, + }; + runtime_ev.ctx.temporal_layer_silu_gate_silu_ok = + ctx.kernel.process_event(silu_ev); + } +}; + +struct effect_run_temporal_layer_silu_gate_mul { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto *linear_in = detail::find_lm_transformer_tensor( + runtime_ev.request.model, runtime_ev.ctx.temporal_layer_index, + "gating.linear_in.weight"); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + const uint64_t gate_dim = projection_dim / 2u; + const float *right = runtime_ev.ctx.gating_projection.data() + gate_dim; + runtime_ev.ctx.temporal_layer_silu_gate_ok = false; + + emel::kernel::event::op_mul gate_ev{ + .src0 = + detail::make_f32_src(runtime_ev.ctx.gating_silu.data(), gate_dim), + .src1 = detail::make_f32_src(right, gate_dim), + .dst = detail::make_f32_dst(runtime_ev.ctx.gated.data(), gate_dim), + }; + runtime_ev.ctx.temporal_layer_silu_gate_ok = + ctx.kernel.process_event(gate_ev); + } +}; + +struct effect_bind_temporal_layer_gating_out { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *linear_in = detail::find_lm_transformer_tensor( + model, layer, "gating.linear_in.weight"); + const auto *linear_out = detail::find_lm_transformer_tensor( + model, layer, "gating.linear_out.weight"); + const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; + (void)gate_dim; + runtime_ev.ctx.temporal_layer_gating_out_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.projection.data(), + static_cast(hidden_dim), 0.0f); + + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*linear_out, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_temporal_layer_gating_out { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *linear_in = detail::find_lm_transformer_tensor( + model, layer, "gating.linear_in.weight"); + const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; + runtime_ev.ctx.temporal_layer_gating_out_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.gated.data(), 1u, gate_dim), + .dst = detail::make_f32_dst(runtime_ev.ctx.projection.data(), 1u, + static_cast(hidden_dim)), + }; + runtime_ev.ctx.temporal_layer_gating_out_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_apply_temporal_layer_ff_residual { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_layer_ff_residual_ok = false; + for (int32_t index = 0; index < hidden_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] += + runtime_ev.ctx.projection[static_cast(index)]; + } + runtime_ev.ctx.temporal_layer_ff_residual_ok = true; + } +}; + +struct effect_advance_temporal_layer { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + ++runtime_ev.ctx.temporal_layer_index; + runtime_ev.ctx.temporal_layer_norm_rms_ok = false; + runtime_ev.ctx.temporal_layer_norm_ok = false; + runtime_ev.ctx.temporal_layer_projection_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.temporal_layer_rope_ok = false; + runtime_ev.ctx.temporal_layer_cache_write_ok = false; + runtime_ev.ctx.temporal_layer_attention_ok = false; + runtime_ev.ctx.temporal_layer_out_projection_ok = false; + runtime_ev.ctx.temporal_layer_residual_ok = false; + runtime_ev.ctx.temporal_layer_norm2_rms_ok = false; + runtime_ev.ctx.temporal_layer_norm2_ok = false; + runtime_ev.ctx.temporal_layer_gating_in_ok = false; + runtime_ev.ctx.temporal_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.temporal_layer_silu_gate_ok = false; + runtime_ev.ctx.temporal_layer_gating_out_ok = false; + runtime_ev.ctx.temporal_layer_ff_residual_ok = false; + runtime_ev.ctx.temporal_logical_position = -1; + runtime_ev.ctx.temporal_physical_position = -1; + } +}; + +struct effect_run_temporal_out_norm_rms { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.temporal_out_norm_rms_ok = false; + runtime_ev.ctx.temporal_out_norm_ok = false; + + std::fill_n(runtime_ev.ctx.row.data(), static_cast(hidden_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim), 0.0f); + + emel::kernel::event::op_rms_norm rms_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.hidden.data(), + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), + static_cast(hidden_dim)), + }; + detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + runtime_ev.ctx.temporal_out_norm_rms_ok = ctx.kernel.process_event(rms_ev); + } +}; + +struct effect_run_temporal_out_norm_scale { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + const auto *out_norm = + detail::find_tensor(runtime_ev.request.model, "lm.out_norm.alpha"); + const auto *alpha = static_cast(out_norm->data); + runtime_ev.ctx.temporal_out_norm_ok = false; + + emel::kernel::event::op_mul mul_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.row.data(), + static_cast(hidden_dim)), + .src1 = detail::make_f32_src(alpha, static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim)), + }; + runtime_ev.ctx.temporal_out_norm_ok = ctx.kernel.process_event(mul_ev); + } +}; + +struct effect_publish_temporal_out_norm { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + std::copy_n(runtime_ev.ctx.normalized.data(), + static_cast(hidden_dim), + runtime_ev.ctx.transformer_out.data()); + } +}; + +struct effect_bind_text_token_logits { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + const auto *text_linear = + detail::find_tensor(runtime_ev.request.model, "lm.text_linear.weight"); + runtime_ev.ctx.text_logits_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*text_linear, runtime_ev.ctx.projection_view); + } +}; + +struct effect_select_text_token { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.text_logits_ok = false; + emel::kernel::event::op_mul_mat_argmax logits_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(&runtime_ev.ctx.best_score, 1u, 1u), + .index_out = &runtime_ev.ctx.best_index, + }; + runtime_ev.ctx.text_logits_ok = ctx.kernel.process_event(logits_ev); + runtime_ev.request.text_token_out = runtime_ev.ctx.best_index; + } +}; + +struct effect_compute_text_token_logits { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t text_card = ctx.session.text_card; + runtime_ev.ctx.text_logits_ok = false; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + emel::kernel::event::op_mul_mat logits_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.logits.data(), 1u, + static_cast(text_card)), + }; + runtime_ev.ctx.text_logits_ok = ctx.kernel.process_event(logits_ev); + } +}; + +struct effect_sample_text_token { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.text_sampling_ok = sampling_ns::sample_top_k_exponential( + runtime_ev.ctx, ctx.session.text_card, ctx.sampling.text_top_k, + ctx.sampling.text_temperature); + runtime_ev.ctx.text_logits_ok = runtime_ev.ctx.text_sampling_ok; + runtime_ev.request.text_token_out = runtime_ev.ctx.best_index; + } +}; + +struct effect_consume_forced_text_sampling { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t text_card = ctx.session.text_card; + runtime_ev.ctx.text_logits_ok = false; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + emel::kernel::event::op_mul_mat logits_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.logits.data(), 1u, + static_cast(text_card)), + }; + runtime_ev.ctx.text_logits_ok = ctx.kernel.process_event(logits_ev); + runtime_ev.ctx.text_sampling_ok = sampling_ns::sample_top_k_exponential( + runtime_ev.ctx, ctx.session.text_card, ctx.sampling.text_top_k, + ctx.sampling.text_temperature); + runtime_ev.ctx.text_logits_ok = + runtime_ev.ctx.text_logits_ok && runtime_ev.ctx.text_sampling_ok; + } +}; + +struct effect_publish_forced_text_token { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.ctx.text_logits_ok = true; + runtime_ev.ctx.best_index = runtime_ev.request.forced_text_token; + runtime_ev.request.text_token_out = runtime_ev.request.forced_text_token; + } +}; + +struct effect_bind_depformer_kv { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.depformer_kv = {}; + runtime_ev.ctx.depformer_kv_bound = ctx.depformer_kv.bind( + ctx.depformer_kv.cache, runtime_ev.request.model, + runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, + runtime_ev.ctx.depformer_kv); + if (runtime_ev.ctx.depformer_kv_bound && + runtime_ev.ctx.depformer_kv.offset != nullptr) { + *runtime_ev.ctx.depformer_kv.offset = 0; + } + } +}; + +struct effect_bind_depformer_text_input_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + (void)ctx; + const int32_t dep_dim = lm.depformer_dim; + runtime_ev.ctx.depformer_input_ok = false; + runtime_ev.ctx.depformer_input_projection_bound = false; + runtime_ev.ctx.depformer_input_projection_ok = false; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.depformer_layer_index = 0; + runtime_ev.ctx.depformer_layer_norm_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm_ok = false; + runtime_ev.ctx.depformer_layer_projection_ok = false; + runtime_ev.ctx.depformer_layer_cache_write_ok = false; + runtime_ev.ctx.depformer_layer_attention_ok = false; + runtime_ev.ctx.depformer_layer_out_projection_ok = false; + runtime_ev.ctx.depformer_layer_residual_ok = false; + runtime_ev.ctx.depformer_layer_norm2_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm2_ok = false; + runtime_ev.ctx.depformer_layer_gating_in_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_ok = false; + runtime_ev.ctx.depformer_layer_gating_out_ok = false; + runtime_ev.ctx.depformer_layer_ff_residual_ok = false; + runtime_ev.ctx.depformer_logits_ok = false; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + std::fill_n(runtime_ev.ctx.hidden.data(), static_cast(dep_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), static_cast(dep_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.projection.data(), static_cast(dep_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.qkv.data(), static_cast(dep_dim) * 3u, + 0.0f); + std::fill_n(runtime_ev.ctx.attention.data(), static_cast(dep_dim), + 0.0f); + + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + const auto *input_projection = detail::find_indexed_tensor( + model, "lm.depformer_in.%d.weight", weight_index); + runtime_ev.ctx.projection_view = {}; + runtime_ev.ctx.depformer_input_projection_bound = detail::bind_tensor_view( + *input_projection, runtime_ev.ctx.projection_view); + } +}; + +struct effect_bind_depformer_audio_input_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + (void)ctx; + const int32_t dep_dim = lm.depformer_dim; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + runtime_ev.ctx.depformer_input_ok = false; + runtime_ev.ctx.depformer_input_projection_bound = false; + runtime_ev.ctx.depformer_input_projection_ok = false; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.depformer_layer_index = 0; + runtime_ev.ctx.depformer_layer_norm_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm_ok = false; + runtime_ev.ctx.depformer_layer_projection_ok = false; + runtime_ev.ctx.depformer_layer_cache_write_ok = false; + runtime_ev.ctx.depformer_layer_attention_ok = false; + runtime_ev.ctx.depformer_layer_out_projection_ok = false; + runtime_ev.ctx.depformer_layer_residual_ok = false; + runtime_ev.ctx.depformer_layer_norm2_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm2_ok = false; + runtime_ev.ctx.depformer_layer_gating_in_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_ok = false; + runtime_ev.ctx.depformer_layer_gating_out_ok = false; + runtime_ev.ctx.depformer_layer_ff_residual_ok = false; + runtime_ev.ctx.depformer_logits_ok = false; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + std::fill_n(runtime_ev.ctx.hidden.data(), static_cast(dep_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), static_cast(dep_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.projection.data(), static_cast(dep_dim), + 0.0f); + std::fill_n(runtime_ev.ctx.qkv.data(), static_cast(dep_dim) * 3u, + 0.0f); + std::fill_n(runtime_ev.ctx.attention.data(), static_cast(dep_dim), + 0.0f); + + const auto *input_projection = detail::find_indexed_tensor( + model, "lm.depformer_in.%d.weight", weight_index); + runtime_ev.ctx.projection_view = {}; + runtime_ev.ctx.depformer_input_projection_bound = detail::bind_tensor_view( + *input_projection, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_depformer_input_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t dep_dim = lm.depformer_dim; + runtime_ev.ctx.depformer_input_projection_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.transformer_out.data(), 1u, + static_cast(hidden_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.hidden.data(), 1u, + static_cast(dep_dim)), + }; + runtime_ev.ctx.depformer_input_projection_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_bind_depformer_text_input_embedding { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; + const auto *text_emb = detail::find_tensor(runtime_ev.request.model, + "lm.depformer_text_emb.weight"); + runtime_ev.ctx.embedding_view = {}; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.embedding_dim = dep_dim; + runtime_ev.ctx.row_index = runtime_ev.request.text_token_out; + runtime_ev.ctx.depformer_input_ok = false; + runtime_ev.ctx.embedding_view_bound = + detail::bind_tensor_view(*text_emb, runtime_ev.ctx.embedding_view); + } +}; + +struct effect_bind_depformer_audio_input_embedding { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + + const auto *audio_emb = detail::find_indexed_tensor( + runtime_ev.request.model, "lm.depformer_emb.%d.weight", codebook - 1); + runtime_ev.ctx.embedding_view = {}; + runtime_ev.ctx.embedding_view_bound = false; + runtime_ev.ctx.embedding_row_ok = false; + runtime_ev.ctx.embedding_dim = dep_dim; + runtime_ev.ctx.row_index = + runtime_ev.request.audio_tokens_out[static_cast(codebook - 1)]; + runtime_ev.ctx.depformer_input_ok = false; + runtime_ev.ctx.embedding_view_bound = + detail::bind_tensor_view(*audio_emb, runtime_ev.ctx.embedding_view); + } +}; + +struct effect_apply_depformer_input_embedding_row { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const int32_t embedding_dim = runtime_ev.ctx.embedding_dim; + runtime_ev.ctx.depformer_input_ok = false; + for (int32_t index = 0; index < embedding_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] += + runtime_ev.ctx.row[static_cast(index)]; + } + runtime_ev.ctx.depformer_input_ok = true; + } +}; + +struct effect_run_depformer_layer_norm_rms { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + runtime_ev.ctx.depformer_layer_norm_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm_ok = false; + + std::fill_n(runtime_ev.ctx.row.data(), static_cast(dep_dim), 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), static_cast(dep_dim), + 0.0f); + + emel::kernel::event::op_rms_norm rms_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.hidden.data(), + static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), + static_cast(dep_dim)), + }; + detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + runtime_ev.ctx.depformer_layer_norm_rms_ok = + ctx.kernel.process_event(rms_ev); + } +}; + +struct effect_run_depformer_layer_norm_scale { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + runtime_ev.ctx.depformer_layer_norm_ok = false; + + const auto *norm1 = + detail::find_depformer_tensor(model, layer, "norm1.alpha"); + const auto *alpha = static_cast(norm1->data); + + emel::kernel::event::op_mul mul_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.row.data(), + static_cast(dep_dim)), + .src1 = detail::make_f32_src(alpha, static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.normalized.data(), + static_cast(dep_dim)), + }; + runtime_ev.ctx.depformer_layer_norm_ok = ctx.kernel.process_event(mul_ev); + } +}; + +struct effect_bind_depformer_layer_projection { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + runtime_ev.ctx.depformer_layer_projection_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.qkv.data(), static_cast(dep_dim) * 3u, + 0.0f); + + const auto *projection = + detail::find_depformer_projection(model, layer, weight_index); + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_depformer_layer_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; + runtime_ev.ctx.depformer_layer_projection_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, + static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.qkv.data(), 1u, + static_cast(dep_dim) * 3u), + }; + runtime_ev.ctx.depformer_layer_projection_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_write_depformer_layer_kv_cache { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + auto &view = runtime_ev.ctx.depformer_kv; + runtime_ev.ctx.depformer_layer_cache_write_ok = false; + + const int32_t logical_position = *view.offset; + const int32_t physical_position = logical_position % view.position_capacity; + runtime_ev.ctx.depformer_logical_position = logical_position; + runtime_ev.ctx.depformer_physical_position = physical_position; + runtime_ev.ctx.depformer_valid_positions = + std::min(logical_position + 1, view.position_capacity); + + const size_t layer_offset = view.layer_cache_offsets[static_cast( + runtime_ev.ctx.depformer_layer_index)]; + const size_t begin = layer_offset + static_cast(physical_position) * + static_cast(dep_dim); + const float *key = runtime_ev.ctx.qkv.data() + static_cast(dep_dim); + const float *value = + runtime_ev.ctx.qkv.data() + static_cast(dep_dim) * 2u; + + for (int32_t index = 0; index < dep_dim; ++index) { + view.key_cache[begin + static_cast(index)] = + emel::kernel::detail::fp32_to_bf16(key[index]); + view.value_cache[begin + static_cast(index)] = + emel::kernel::detail::fp32_to_bf16(value[index]); + } + runtime_ev.ctx.depformer_layer_cache_write_ok = true; + } +}; + +struct effect_run_depformer_layer_attention { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const auto &view = runtime_ev.ctx.depformer_kv; + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t head_dim = dep_dim / lm.depformer_num_heads; + const int32_t capacity = view.position_capacity; + const int32_t logical_position = runtime_ev.ctx.depformer_logical_position; + const float scale = 1.0f / std::sqrt(static_cast(head_dim)); + const size_t layer_offset = view.layer_cache_offsets[static_cast( + runtime_ev.ctx.depformer_layer_index)]; + runtime_ev.ctx.depformer_layer_attention_ok = false; + std::fill_n(runtime_ev.ctx.attention.data(), static_cast(dep_dim), + 0.0f); + + for (int32_t head = 0; head < lm.depformer_num_heads; ++head) { + const int32_t head_offset = head * head_dim; + const float *q_head = + runtime_ev.ctx.qkv.data() + static_cast(head_offset); + for (int32_t dim = 0; dim < head_dim; ++dim) { + runtime_ev.ctx.q_bf16[static_cast(dim)] = + emel::kernel::detail::fp32_to_bf16(q_head[dim]); + } + for (int32_t physical = 0; physical < capacity; ++physical) { + const bool visible = + logical_position >= capacity || physical <= logical_position; + const size_t cache_begin = + layer_offset + + static_cast(physical) * static_cast(dep_dim) + + static_cast(head_offset); + runtime_ev.ctx.attention_scores[static_cast(physical)] = + visible ? emel::kernel::detail::vec_dot_bf16_ggml( + head_dim, view.key_cache.data() + cache_begin, + runtime_ev.ctx.q_bf16.data()) * + scale + : -std::numeric_limits::infinity(); + } + + emel::kernel::detail::soft_max_row_ggml( + capacity, runtime_ev.ctx.attention_scores.data()); + for (int32_t physical = 0; physical < capacity; ++physical) { + runtime_ev.ctx.attention_weights_bf16[static_cast(physical)] = + emel::kernel::detail::fp32_to_bf16( + runtime_ev.ctx.attention_scores[static_cast(physical)]); + } + + float *attention_head = + runtime_ev.ctx.attention.data() + static_cast(head_offset); + for (int32_t dim = 0; dim < head_dim; ++dim) { + double sum = 0.0; + for (int32_t physical = 0; physical < capacity; ++physical) { + const size_t value_index = + layer_offset + + static_cast(physical) * static_cast(dep_dim) + + static_cast(head_offset + dim); + sum += + static_cast( + emel::kernel::detail::bf16_to_fp32( + view.value_cache[value_index]) * + emel::kernel::detail::bf16_to_fp32( + runtime_ev.ctx.attention_weights_bf16[static_cast( + physical)])); + } + attention_head[dim] = static_cast(sum); + } + } + runtime_ev.ctx.depformer_layer_attention_ok = true; + } +}; + +struct effect_bind_depformer_layer_out_projection { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + runtime_ev.ctx.depformer_layer_out_projection_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.projection.data(), static_cast(dep_dim), + 0.0f); + + const auto *projection = detail::find_depformer_codebook_tensor( + model, layer, "self_attn.out_projs.%d.weight", weight_index); + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_depformer_layer_out_projection { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; + runtime_ev.ctx.depformer_layer_out_projection_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.attention.data(), 1u, + static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.projection.data(), 1u, + static_cast(dep_dim)), + }; + runtime_ev.ctx.depformer_layer_out_projection_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_apply_depformer_layer_attention_residual { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; + runtime_ev.ctx.depformer_layer_residual_ok = false; + for (int32_t index = 0; index < dep_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] += + runtime_ev.ctx.projection[static_cast(index)]; + } + runtime_ev.ctx.depformer_layer_residual_ok = true; + } +}; + +struct effect_run_depformer_layer_norm2_rms { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + runtime_ev.ctx.depformer_layer_norm2_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm2_ok = false; + + std::fill_n(runtime_ev.ctx.row.data(), static_cast(dep_dim), 0.0f); + std::fill_n(runtime_ev.ctx.normalized.data(), static_cast(dep_dim), + 0.0f); + + emel::kernel::event::op_rms_norm rms_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.hidden.data(), + static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), + static_cast(dep_dim)), + }; + detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + runtime_ev.ctx.depformer_layer_norm2_rms_ok = + ctx.kernel.process_event(rms_ev); + } +}; + +struct effect_run_depformer_layer_norm2_scale { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + runtime_ev.ctx.depformer_layer_norm2_ok = false; + + const auto *norm2 = + detail::find_depformer_tensor(model, layer, "norm2.alpha"); + const auto *alpha = static_cast(norm2->data); + + emel::kernel::event::op_mul mul_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.row.data(), + static_cast(dep_dim)), + .src1 = detail::make_f32_src(alpha, static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.normalized.data(), + static_cast(dep_dim)), + }; + runtime_ev.ctx.depformer_layer_norm2_ok = ctx.kernel.process_event(mul_ev); + } +}; + +struct effect_bind_depformer_layer_gating_in { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + const auto *linear_in = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_in.weight", weight_index); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + runtime_ev.ctx.depformer_layer_gating_in_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.gating_projection.data(), + static_cast(projection_dim), 0.0f); + + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*linear_in, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_depformer_layer_gating_in { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + const auto *linear_in = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_in.weight", weight_index); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + runtime_ev.ctx.depformer_layer_gating_in_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, + static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.gating_projection.data(), 1u, + projection_dim), + }; + runtime_ev.ctx.depformer_layer_gating_in_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_run_depformer_layer_silu_gate_silu { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto *linear_in = detail::find_depformer_codebook_tensor( + runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, + "gating.%d.linear_in.weight", + runtime_ev.ctx.depformer_weight_index); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + const uint64_t gate_dim = projection_dim / 2u; + runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_ok = false; + std::fill_n(runtime_ev.ctx.gating_silu.data(), + static_cast(gate_dim), 0.0f); + std::fill_n(runtime_ev.ctx.gated.data(), static_cast(gate_dim), + 0.0f); + + emel::kernel::event::op_unary silu_ev{ + .src0 = detail::make_f32_src(runtime_ev.ctx.gating_projection.data(), + gate_dim), + .dst = + detail::make_f32_dst(runtime_ev.ctx.gating_silu.data(), gate_dim), + .subop = emel::kernel::event::unary_subop::silu, + }; + runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = + ctx.kernel.process_event(silu_ev); + } +}; + +struct effect_run_depformer_layer_silu_gate_mul { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto *linear_in = detail::find_depformer_codebook_tensor( + runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, + "gating.%d.linear_in.weight", + runtime_ev.ctx.depformer_weight_index); + const uint64_t projection_dim = static_cast(linear_in->dims[1]); + const uint64_t gate_dim = projection_dim / 2u; + const float *right = runtime_ev.ctx.gating_projection.data() + gate_dim; + runtime_ev.ctx.depformer_layer_silu_gate_ok = false; + + emel::kernel::event::op_mul gate_ev{ + .src0 = + detail::make_f32_src(runtime_ev.ctx.gating_silu.data(), gate_dim), + .src1 = detail::make_f32_src(right, gate_dim), + .dst = detail::make_f32_dst(runtime_ev.ctx.gated.data(), gate_dim), + }; + runtime_ev.ctx.depformer_layer_silu_gate_ok = + ctx.kernel.process_event(gate_ev); + } +}; + +struct effect_bind_depformer_layer_gating_out { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + const auto *linear_in = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_in.weight", weight_index); + const auto *linear_out = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_out.weight", weight_index); + const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; + (void)gate_dim; + runtime_ev.ctx.depformer_layer_gating_out_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + std::fill_n(runtime_ev.ctx.projection.data(), static_cast(dep_dim), + 0.0f); + + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*linear_out, runtime_ev.ctx.projection_view); + } +}; + +struct effect_run_depformer_layer_gating_out { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + const auto *linear_in = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_in.weight", weight_index); + const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; + runtime_ev.ctx.depformer_layer_gating_out_ok = false; + emel::kernel::event::op_mul_mat projection_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.gated.data(), 1u, gate_dim), + .dst = detail::make_f32_dst(runtime_ev.ctx.projection.data(), 1u, + static_cast(dep_dim)), + }; + runtime_ev.ctx.depformer_layer_gating_out_ok = + ctx.kernel.process_event(projection_ev); + } +}; + +struct effect_apply_depformer_layer_ff_residual { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; + runtime_ev.ctx.depformer_layer_ff_residual_ok = false; + for (int32_t index = 0; index < dep_dim; ++index) { + runtime_ev.ctx.hidden[static_cast(index)] += + runtime_ev.ctx.projection[static_cast(index)]; + } + runtime_ev.ctx.depformer_layer_ff_residual_ok = true; + } +}; + +struct effect_advance_depformer_layer { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + ++runtime_ev.ctx.depformer_layer_index; + runtime_ev.ctx.depformer_layer_norm_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm_ok = false; + runtime_ev.ctx.depformer_layer_projection_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.depformer_layer_cache_write_ok = false; + runtime_ev.ctx.depformer_layer_attention_ok = false; + runtime_ev.ctx.depformer_layer_out_projection_ok = false; + runtime_ev.ctx.depformer_layer_residual_ok = false; + runtime_ev.ctx.depformer_layer_norm2_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm2_ok = false; + runtime_ev.ctx.depformer_layer_gating_in_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_ok = false; + runtime_ev.ctx.depformer_layer_gating_out_ok = false; + runtime_ev.ctx.depformer_layer_ff_residual_ok = false; + runtime_ev.ctx.depformer_logical_position = -1; + runtime_ev.ctx.depformer_physical_position = -1; + runtime_ev.ctx.depformer_valid_positions = 0; + } +}; + +struct effect_bind_depformer_token_logits { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + const auto *linear = detail::find_indexed_tensor( + runtime_ev.request.model, "lm.linears.%d.weight", codebook); + runtime_ev.ctx.depformer_logits_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*linear, runtime_ev.ctx.projection_view); + } +}; + +struct effect_select_depformer_token { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + runtime_ev.ctx.depformer_logits_ok = false; + emel::kernel::event::op_mul_mat_argmax logits_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.hidden.data(), 1u, + static_cast(dep_dim)), + .dst = detail::make_f32_dst(&runtime_ev.ctx.best_score, 1u, 1u), + .index_out = &runtime_ev.ctx.best_index, + }; + runtime_ev.ctx.depformer_logits_ok = ctx.kernel.process_event(logits_ev); + } +}; + +struct effect_compute_depformer_token_logits { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t audio_card = ctx.session.audio_card; + runtime_ev.ctx.depformer_logits_ok = false; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + emel::kernel::event::op_mul_mat logits_ev{ + .src0 = runtime_ev.ctx.projection_view, + .src1 = detail::make_f32_src(runtime_ev.ctx.hidden.data(), 1u, + static_cast(dep_dim)), + .dst = detail::make_f32_dst(runtime_ev.ctx.logits.data(), 1u, + static_cast(audio_card)), + }; + runtime_ev.ctx.depformer_logits_ok = ctx.kernel.process_event(logits_ev); + } +}; + +struct effect_sample_depformer_token { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.depformer_sampling_ok = + sampling_ns::sample_top_k_exponential( + runtime_ev.ctx, ctx.session.audio_card, ctx.sampling.audio_top_k, + ctx.sampling.audio_temperature); + runtime_ev.ctx.depformer_logits_ok = runtime_ev.ctx.depformer_sampling_ok; + } +}; + +struct effect_publish_depformer_token { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + runtime_ev.request.audio_tokens_out[static_cast(codebook)] = + runtime_ev.ctx.best_index; + ++(*runtime_ev.ctx.depformer_kv.offset); + } +}; + +struct effect_advance_depformer_codebook { + void operator()(const event::step_run &runtime_ev, + const context &) const noexcept { + ++runtime_ev.ctx.depformer_codebook_index; + runtime_ev.ctx.depformer_input_ok = false; + runtime_ev.ctx.depformer_layer_index = 0; + runtime_ev.ctx.depformer_layer_norm_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm_ok = false; + runtime_ev.ctx.depformer_layer_projection_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.depformer_layer_cache_write_ok = false; + runtime_ev.ctx.depformer_layer_attention_ok = false; + runtime_ev.ctx.depformer_layer_out_projection_ok = false; + runtime_ev.ctx.depformer_layer_residual_ok = false; + runtime_ev.ctx.depformer_layer_norm2_rms_ok = false; + runtime_ev.ctx.depformer_layer_norm2_ok = false; + runtime_ev.ctx.depformer_layer_gating_in_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; + runtime_ev.ctx.depformer_layer_silu_gate_ok = false; + runtime_ev.ctx.depformer_layer_gating_out_ok = false; + runtime_ev.ctx.depformer_layer_ff_residual_ok = false; + runtime_ev.ctx.depformer_logits_ok = false; + runtime_ev.ctx.depformer_logical_position = -1; + runtime_ev.ctx.depformer_physical_position = -1; + runtime_ev.ctx.depformer_valid_positions = 0; + runtime_ev.ctx.depformer_weight_index = -1; + } +}; + +struct effect_bind_temporal_kv { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.temporal_kv = {}; + runtime_ev.ctx.temporal_kv_bound = ctx.temporal_kv.bind( + ctx.temporal_kv.cache, runtime_ev.request.model, + runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, + runtime_ev.ctx.temporal_kv); + } +}; + +template struct effect_store_error_out { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + *runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_emit_initialize_done { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.request.on_done(events::initialize_done{ + .request = &runtime_ev.request, + .n_q = ctx.session.codebook_count - 1, + .dep_q = ctx.session.dep_q, + }); + } +}; + +struct effect_emit_initialize_error { + void operator()(const event::initialize_run &runtime_ev, + context &) const noexcept { + runtime_ev.request.on_error(events::initialize_error{ + .request = &runtime_ev.request, + .err = runtime_ev.ctx.err, + }); + } +}; + +struct effect_reset_session { + void operator()(const event::reset &, context &ctx) const noexcept { + ctx.session = {}; + } +}; + +struct effect_mark_unexpected { + template + void operator()(const unexpected_event_type &ev, context &) const noexcept { + if constexpr (requires { ev.ctx.err; }) { + ev.ctx.err = detail_ns::to_error(error::unexpected_event); + } + } +}; + +struct effect_mark_unexpected_and_store { + template + void operator()(const unexpected_event_type &ev, + context &ctx) const noexcept { + effect_mark_unexpected{}(ev, ctx); + if constexpr (requires { + ev.ctx.err; + ev.request.error_out; + }) { + *ev.request.error_out = ev.ctx.err; + } + } +}; + +} // namespace emel::speech::generator::moshi::executor::action diff --git a/src/emel/speech/generator/moshi/executor/any.hpp b/src/emel/speech/generator/moshi/executor/any.hpp new file mode 100644 index 00000000..827d2823 --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/any.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include "emel/speech/generator/moshi/executor/sm.hpp" + +namespace emel::speech::generator::moshi::executor { + +inline bool dispatch_graph_step( + void *executor_ptr, + const emel::speech::generator::moshi::event::graph_step &ev) noexcept { + return static_cast(executor_ptr)->process_event(ev); +} + +inline emel::speech::generator::moshi::action::graph_binding +bind_graph_executor(sm &executor) noexcept { + return emel::speech::generator::moshi::action::bind_graph_executor( + &executor, dispatch_graph_step); +} + +using temporal_kv_binding = action::temporal_kv_binding; +using depformer_kv_binding = action::depformer_kv_binding; +using kv_bindings = action::kv_bindings; + +inline temporal_kv_binding +bind_temporal_kv_cache(void *cache, + action::temporal_kv_bind_fn &bind) noexcept { + return action::bind_temporal_kv_cache(cache, bind); +} + +inline depformer_kv_binding +bind_depformer_kv_cache(void *cache, + action::depformer_kv_bind_fn &bind) noexcept { + return action::bind_depformer_kv_cache(cache, bind); +} + +inline kv_bindings +bind_kv_caches(const temporal_kv_binding &temporal, + const depformer_kv_binding &depformer) noexcept { + return action::bind_kv_caches(temporal, depformer); +} + +using MoshiExecutor = sm; + +} // namespace emel::speech::generator::moshi::executor diff --git a/src/emel/speech/generator/moshi/executor/context.hpp b/src/emel/speech/generator/moshi/executor/context.hpp new file mode 100644 index 00000000..22519a79 --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/context.hpp @@ -0,0 +1,87 @@ +#pragma once + +#include + +#include "emel/kernel/sm.hpp" +#include "emel/memory/view.hpp" +#include "emel/model/data.hpp" +#include "emel/model/moshi/detail.hpp" +#include "emel/speech/generator/moshi/executor/detail.hpp" + +namespace emel::speech::generator::moshi::executor::action { + +using temporal_kv_bind_fn = bool(void *, const emel::model::data &, + const emel::memory::view::snapshot &, int32_t, + detail::temporal_kv_view &); + +using depformer_kv_bind_fn = bool(void *, const emel::model::data &, + const emel::memory::view::snapshot &, int32_t, + detail::depformer_kv_view &); + +struct temporal_kv_binding { + void *cache = nullptr; + temporal_kv_bind_fn *bind = nullptr; +}; + +struct depformer_kv_binding { + void *cache = nullptr; + depformer_kv_bind_fn *bind = nullptr; +}; + +struct kv_bindings { + temporal_kv_binding temporal = {}; + depformer_kv_binding depformer = {}; +}; + +struct runtime { + const emel::model::data *model = nullptr; + emel::model::moshi::detail::execution_contract contract = {}; + int32_t codebook_count = 0; + int32_t dep_q = 0; + int32_t text_card = 0; + int32_t audio_card = 0; + int32_t hidden_dim = 0; +}; + +struct sampling_config { + bool enabled = false; + bool consume_forced_text = false; + float audio_temperature = 0.0f; + float text_temperature = 0.0f; + int32_t audio_top_k = 0; + int32_t text_top_k = 0; + uint32_t seed = 1u; +}; + +struct context { + context() = default; + explicit context(const temporal_kv_binding &kv_binding) + : temporal_kv(kv_binding) {} + explicit context(const kv_bindings &kv_binding_set) + : temporal_kv(kv_binding_set.temporal), + depformer_kv(kv_binding_set.depformer) {} + + runtime session = {}; + sampling_config sampling = {}; + temporal_kv_binding temporal_kv = {}; + depformer_kv_binding depformer_kv = {}; + emel::kernel::sm kernel = {}; +}; + +inline temporal_kv_binding +bind_temporal_kv_cache(void *cache, temporal_kv_bind_fn &bind) noexcept { + return temporal_kv_binding{.cache = cache, .bind = &bind}; +} + +inline depformer_kv_binding +bind_depformer_kv_cache(void *cache, depformer_kv_bind_fn &bind) noexcept { + return depformer_kv_binding{.cache = cache, .bind = &bind}; +} + +inline kv_bindings +bind_kv_caches(const temporal_kv_binding &temporal, + const depformer_kv_binding &depformer) noexcept { + return kv_bindings{.temporal = temporal, .depformer = depformer}; +} + +} // namespace emel::speech::generator::moshi::executor::action diff --git a/src/emel/speech/generator/moshi/executor/detail.hpp b/src/emel/speech/generator/moshi/executor/detail.hpp new file mode 100644 index 00000000..ae4871b0 --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/detail.hpp @@ -0,0 +1,307 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "emel/kernel/detail.hpp" +#include "emel/kernel/events.hpp" +#include "emel/memory/view.hpp" +#include "emel/model/data.hpp" + +namespace emel::speech::generator::moshi::executor::detail { + +using dtype = emel::kernel::event::dtype; +using tensor_record = emel::model::data::tensor_record; +using tensor_view = emel::kernel::event::tensor_view; +using tensor_view_mut = emel::kernel::event::tensor_view_mut; + +inline constexpr uint64_t k_max_hidden_dim = 8192u; +inline constexpr uint64_t k_max_qkv_dim = k_max_hidden_dim * 3u; +inline constexpr uint64_t k_max_gating_projection_dim = k_max_hidden_dim * 8u; +inline constexpr uint64_t k_max_gating_dim = k_max_gating_projection_dim / 2u; +inline constexpr uint64_t k_max_temporal_context = 8192u; +inline constexpr uint64_t k_max_depformer_context = 512u; +inline constexpr uint64_t k_max_sampling_card = 65536u; +inline constexpr uint64_t k_max_sampling_top_k = 1024u; +inline constexpr int32_t k_token_zero = -1; +inline constexpr float k_rms_norm_eps = 1.0e-8f; + +struct streaming_kv_view { + std::span key_cache = {}; + std::span value_cache = {}; + std::span layer_cache_offsets = {}; + int32_t *offset = nullptr; + int32_t layer_count = 0; + int32_t position_capacity = 0; + int32_t block_tokens = 0; + int32_t kv_dim = 0; +}; + +using temporal_kv_view = streaming_kv_view; +using depformer_kv_view = streaming_kv_view; + +template +void fill_default_nb(tensor_type &tensor) noexcept { + const uint64_t elem_size = emel::kernel::detail::dtype_size_bytes( + emel::kernel::detail::dtype_code(tensor.type)); + tensor.nb[0] = elem_size; + tensor.nb[1] = tensor.nb[0] * tensor.ne[0]; + tensor.nb[2] = tensor.nb[1] * tensor.ne[1]; + tensor.nb[3] = tensor.nb[2] * tensor.ne[2]; +} + +inline const tensor_record *find_tensor(const emel::model::data &model, + const std::string_view name) noexcept { + for (uint32_t index = 0u; index < model.n_tensors; ++index) { + const auto &tensor = model.tensors[index]; + if (emel::model::tensor_name_view(model, tensor) == name) { + return &tensor; + } + } + return nullptr; +} + +inline const tensor_record *find_indexed_tensor(const emel::model::data &model, + const char *format, + const int32_t index) noexcept { + char buffer[96] = {}; + const int written = std::snprintf(buffer, sizeof(buffer), format, index); + if (written <= 0 || static_cast(written) >= sizeof(buffer)) { + return nullptr; + } + return find_tensor(model, + std::string_view{buffer, static_cast(written)}); +} + +inline const tensor_record * +find_lm_transformer_tensor(const emel::model::data &model, const int32_t layer, + const char *suffix) noexcept { + char buffer[128] = {}; + const int written = std::snprintf( + buffer, sizeof(buffer), "lm.transformer.layers.%d.%s", layer, suffix); + if (written <= 0 || static_cast(written) >= sizeof(buffer)) { + return nullptr; + } + return find_tensor(model, + std::string_view{buffer, static_cast(written)}); +} + +inline const tensor_record * +find_lm_transformer_projection(const emel::model::data &model, + const int32_t layer) noexcept { + const auto *split = + find_lm_transformer_tensor(model, layer, "self_attn.in_projs.0.weight"); + if (split != nullptr) { + return split; + } + return find_lm_transformer_tensor(model, layer, "self_attn.in_proj_weight"); +} + +inline const tensor_record * +find_depformer_tensor(const emel::model::data &model, const int32_t layer, + const char *suffix) noexcept { + char buffer[160] = {}; + const int written = std::snprintf(buffer, sizeof(buffer), + "lm.depformer.layers.%d.%s", layer, suffix); + if (written <= 0 || static_cast(written) >= sizeof(buffer)) { + return nullptr; + } + return find_tensor(model, + std::string_view{buffer, static_cast(written)}); +} + +inline const tensor_record * +find_depformer_codebook_tensor(const emel::model::data &model, + const int32_t layer, const char *format, + const int32_t codebook) noexcept { + char suffix[128] = {}; + const int suffix_written = + std::snprintf(suffix, sizeof(suffix), format, codebook); + if (suffix_written <= 0 || + static_cast(suffix_written) >= sizeof(suffix)) { + return nullptr; + } + return find_depformer_tensor(model, layer, suffix); +} + +inline const tensor_record * +find_depformer_projection(const emel::model::data &model, const int32_t layer, + const int32_t codebook) noexcept { + const auto *split = find_depformer_codebook_tensor( + model, layer, "self_attn.in_projs.%d.weight", codebook); + if (split != nullptr) { + return split; + } + return find_depformer_tensor(model, layer, "self_attn.in_proj_weight"); +} + +inline bool supported_get_rows_dtype(const dtype type) noexcept { + const auto code = emel::kernel::detail::dtype_code(type); + return code == emel::kernel::detail::dtype_f32 || + code == emel::kernel::detail::dtype_f16 || + code == emel::kernel::detail::dtype_bf16 || + code == emel::kernel::detail::dtype_q4_0 || + code == emel::kernel::detail::dtype_q8_0 || + code == emel::kernel::detail::dtype_q4_k; +} + +inline bool supported_argmax_dtype(const dtype type) noexcept { + const auto code = emel::kernel::detail::dtype_code(type); + return code == emel::kernel::detail::dtype_f32 || + emel::kernel::detail::is_native_quantized_dtype(code) || + emel::kernel::detail::is_packed_q4_vector_dtype(code); +} + +inline bool supported_mul_mat_dtype(const dtype type) noexcept { + const auto code = emel::kernel::detail::dtype_code(type); + return code == emel::kernel::detail::dtype_f32 || + code == emel::kernel::detail::dtype_f16 || + emel::kernel::detail::is_native_quantized_dtype(code) || + emel::kernel::detail::is_packed_q4_vector_dtype(code); +} + +inline bool is_quantized_row_tensor(const dtype type) noexcept { + const auto code = emel::kernel::detail::dtype_code(type); + return emel::kernel::detail::is_native_quantized_dtype(code) || + emel::kernel::detail::is_packed_q4_vector_dtype(code); +} + +inline bool bind_tensor_view(const tensor_record &tensor, + tensor_view &view) noexcept { + if (tensor.data == nullptr || tensor.n_dims <= 0 || tensor.dims[0] <= 0) { + return false; + } + + view = {}; + view.data = tensor.data; + view.type = static_cast(tensor.type); + view.ne = { + static_cast(tensor.dims[0]), + tensor.n_dims > 1 ? static_cast(tensor.dims[1]) : 1u, + tensor.n_dims > 2 ? static_cast(tensor.dims[2]) : 1u, + tensor.n_dims > 3 ? static_cast(tensor.dims[3]) : 1u, + }; + + if (is_quantized_row_tensor(view.type)) { + const uint8_t code = emel::kernel::detail::dtype_code(view.type); + if (emel::kernel::detail::is_packed_q4_vector_dtype(code)) { + const uint64_t group_count = + emel::kernel::detail::quant::packed_q4_k_x8_group_count(view.ne[1]); + const size_t group_bytes = + emel::kernel::detail::quant::packed_q4_k_x8_group_storage_bytes( + view.ne[0]); + if (group_count == 0u || group_bytes == 0u) { + return false; + } + view.nb[0] = 1u; + view.nb[1] = group_bytes; + view.nb[2] = group_bytes * group_count; + view.nb[3] = view.nb[2]; + return true; + } + const size_t row_bytes = + emel::kernel::detail::quantized_row_storage_bytes(code, view.ne[0]); + if (row_bytes == 0u) { + return false; + } + view.nb[0] = 1u; + view.nb[1] = row_bytes; + view.nb[2] = row_bytes * view.ne[1]; + view.nb[3] = view.nb[2] * view.ne[2]; + return true; + } + + fill_default_nb(view); + return view.nb[0] != 0u; +} + +inline tensor_view make_f32_src(const float *data, const uint64_t ne0, + const uint64_t ne1 = 1u) noexcept { + tensor_view view{}; + view.data = data; + view.type = dtype::f32; + view.ne = {ne0, ne1, 1u, 1u}; + fill_default_nb(view); + return view; +} + +inline tensor_view make_i32_src(const int32_t *data, + const uint64_t ne0) noexcept { + tensor_view view{}; + view.data = data; + view.type = dtype::i32; + view.ne = {ne0, 1u, 1u, 1u}; + fill_default_nb(view); + return view; +} + +inline tensor_view_mut make_f32_dst(float *data, const uint64_t ne0, + const uint64_t ne1 = 1u) noexcept { + tensor_view_mut view{}; + view.data = data; + view.type = dtype::f32; + view.ne = {ne0, ne1, 1u, 1u}; + fill_default_nb(view); + return view; +} + +template +inline void set_op_param_f32(event_type &ev, const uint32_t slot, + const float value) noexcept { + const auto offset = slot * static_cast(sizeof(float)); + if (offset + sizeof(float) <= ev.op_params.size()) { + auto *bytes = ev.op_params.data() + offset; + std::memcpy(bytes, &value, sizeof(float)); + ev.op_params_size = offset + static_cast(sizeof(float)); + } +} + +template +inline void set_op_param_i32(event_type &ev, const uint32_t slot, + const int32_t value) noexcept { + const auto offset = slot * static_cast(sizeof(int32_t)); + if (offset + sizeof(int32_t) <= ev.op_params.size()) { + auto *bytes = ev.op_params.data() + offset; + std::memcpy(bytes, &value, sizeof(int32_t)); + ev.op_params_size = offset + static_cast(sizeof(int32_t)); + } +} + +inline bool tensor_shape(const tensor_record *tensor, const int64_t ne0, + const int64_t ne1 = 1) noexcept { + return tensor != nullptr && tensor->data != nullptr && tensor->n_dims >= 1 && + tensor->dims[0] == ne0 && + (tensor->n_dims == 1 || tensor->dims[1] == ne1); +} + +inline int32_t +current_logical_position(const emel::memory::view::snapshot &snapshot, + const int32_t sequence_id) noexcept { + const int32_t length = snapshot.sequence_length(sequence_id); + return length > 0 ? length - 1 : -1; +} + +inline int32_t physical_position(const emel::memory::view::snapshot &snapshot, + const int32_t sequence_id, + const int32_t logical_position) noexcept { + if (logical_position < 0 || snapshot.block_tokens <= 0) { + return -1; + } + const int32_t block_id = + snapshot.lookup_kv_block(sequence_id, logical_position); + if (block_id < 0) { + return -1; + } + return block_id * snapshot.block_tokens + + (logical_position % snapshot.block_tokens); +} + +inline bool token_in_embedding_range(const int32_t token, + const int32_t card) noexcept { + return token >= k_token_zero && token <= card; +} + +} // namespace emel::speech::generator::moshi::executor::detail diff --git a/src/emel/speech/generator/moshi/executor/errors.hpp b/src/emel/speech/generator/moshi/executor/errors.hpp new file mode 100644 index 00000000..b932f880 --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/errors.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "emel/error/error.hpp" + +namespace emel::speech::generator::moshi::executor { + +enum class error : emel::error::type { + none = 0, + not_initialized = 1, + bind_failed = 2, + request_shape = 3, + model_mismatch = 4, + graph_execution_unsupported = 5, + unexpected_event = 6, +}; + +} // namespace emel::speech::generator::moshi::executor diff --git a/src/emel/speech/generator/moshi/executor/events.hpp b/src/emel/speech/generator/moshi/executor/events.hpp new file mode 100644 index 00000000..20a3ee55 --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/events.hpp @@ -0,0 +1,159 @@ +#pragma once + +#include + +#include "emel/callback.hpp" +#include "emel/error/error.hpp" +#include "emel/model/data.hpp" +#include "emel/speech/generator/moshi/events.hpp" +#include "emel/speech/generator/moshi/executor/detail.hpp" +#include "emel/speech/generator/moshi/executor/errors.hpp" + +namespace emel::speech::generator::moshi::executor::events { + +struct initialize_done; +struct initialize_error; + +} // namespace emel::speech::generator::moshi::executor::events + +namespace emel::speech::generator::moshi::executor::event { + +struct initialize { + explicit initialize(const emel::model::data &model_ref) noexcept + : model(model_ref) {} + + const emel::model::data &model; + bool sampling_enabled = false; + bool sampling_consume_forced_text = false; + float sampling_audio_temperature = 0.0f; + float sampling_text_temperature = 0.0f; + int32_t sampling_audio_top_k = 0; + int32_t sampling_text_top_k = 0; + uint32_t sampling_seed = 1u; + emel::error::type *error_out = nullptr; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct initialize_ctx { + emel::error::type err = emel::error::cast(error::none); +}; + +struct step_ctx { + emel::error::type err = emel::error::cast(error::none); + bool input_embedding_ok = false; + bool input_text_embedding_ok = false; + bool input_audio_embedding_ok = false; + bool embedding_view_bound = false; + bool embedding_row_ok = false; + bool projection_view_bound = false; + bool temporal_kv_bound = false; + bool temporal_layer_norm_rms_ok = false; + bool temporal_layer_norm_ok = false; + bool temporal_layer_projection_ok = false; + bool temporal_layer_rope_ok = false; + bool temporal_layer_cache_write_ok = false; + bool temporal_layer_attention_ok = false; + bool temporal_layer_out_projection_ok = false; + bool temporal_layer_residual_ok = false; + bool temporal_layer_norm2_rms_ok = false; + bool temporal_layer_norm2_ok = false; + bool temporal_layer_gating_in_ok = false; + bool temporal_layer_silu_gate_silu_ok = false; + bool temporal_layer_silu_gate_ok = false; + bool temporal_layer_gating_out_ok = false; + bool temporal_layer_ff_residual_ok = false; + bool temporal_out_norm_rms_ok = false; + bool temporal_out_norm_ok = false; + bool text_logits_ok = false; + bool text_sampling_ok = false; + bool depformer_kv_bound = false; + bool depformer_input_ok = false; + bool depformer_input_projection_bound = false; + bool depformer_input_projection_ok = false; + bool depformer_layer_norm_rms_ok = false; + bool depformer_layer_norm_ok = false; + bool depformer_layer_projection_ok = false; + bool depformer_layer_cache_write_ok = false; + bool depformer_layer_attention_ok = false; + bool depformer_layer_out_projection_ok = false; + bool depformer_layer_residual_ok = false; + bool depformer_layer_norm2_rms_ok = false; + bool depformer_layer_norm2_ok = false; + bool depformer_layer_gating_in_ok = false; + bool depformer_layer_silu_gate_silu_ok = false; + bool depformer_layer_silu_gate_ok = false; + bool depformer_layer_gating_out_ok = false; + bool depformer_layer_ff_residual_ok = false; + bool depformer_logits_ok = false; + bool depformer_sampling_ok = false; + int32_t row_index = 0; + int32_t embedding_dim = 0; + int32_t best_index = -1; + int32_t input_audio_codebook_index = 0; + int32_t temporal_layer_index = 0; + int32_t temporal_logical_position = -1; + int32_t temporal_physical_position = -1; + int32_t depformer_codebook_index = 0; + int32_t depformer_weight_index = -1; + int32_t depformer_layer_index = 0; + int32_t depformer_logical_position = -1; + int32_t depformer_physical_position = -1; + int32_t depformer_valid_positions = 0; + float best_score = 0.0f; + detail::temporal_kv_view temporal_kv = {}; + detail::depformer_kv_view depformer_kv = {}; + detail::tensor_view embedding_view = {}; + detail::tensor_view projection_view = {}; + alignas(64) std::array logits = {}; + alignas(64) std::array top_scores = {}; + alignas(64) + std::array top_indices = {}; + alignas(64) std::array row = {}; + alignas(64) std::array hidden = {}; + alignas(64) std::array transformer_out = {}; + alignas(64) std::array normalized = {}; + alignas(64) std::array attention = {}; + alignas(64) std::array projection = {}; + alignas(64) std::array qkv = {}; + alignas(64) std::array rope = {}; + alignas(64) + std::array gating_projection = + {}; + alignas(64) std::array gating_silu = {}; + alignas(64) std::array gated = {}; + alignas(64) + std::array attention_scores = {}; + alignas(64) std::array q_bf16 = {}; + alignas(64) std::array< + uint16_t, detail::k_max_temporal_context> attention_weights_bf16 = {}; +}; + +struct initialize_run { + const initialize &request; + initialize_ctx &ctx; +}; + +struct step_run { + const emel::speech::generator::moshi::event::graph_step &request; + step_ctx &ctx; +}; + +struct reset {}; + +} // namespace emel::speech::generator::moshi::executor::event + +namespace emel::speech::generator::moshi::executor::events { + +struct initialize_done { + const event::initialize *request = nullptr; + int32_t n_q = 0; + int32_t dep_q = 0; +}; + +struct initialize_error { + const event::initialize *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +} // namespace emel::speech::generator::moshi::executor::events diff --git a/src/emel/speech/generator/moshi/executor/guards.hpp b/src/emel/speech/generator/moshi/executor/guards.hpp new file mode 100644 index 00000000..5d78a0aa --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/guards.hpp @@ -0,0 +1,1942 @@ +#pragma once + +#include "emel/model/loader/errors.hpp" +#include "emel/model/moshi/detail.hpp" +#include "emel/speech/generator/moshi/executor/context.hpp" +#include "emel/speech/generator/moshi/executor/detail.hpp" +#include "emel/speech/generator/moshi/executor/events.hpp" + +namespace emel::speech::generator::moshi::executor::guard { + +struct guard_bind_contract_valid { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + return emel::model::moshi::detail::validate_execution_contract(model) == + emel::error::cast(emel::model::loader::error::none) && + model.moshi_component_id == emel::model::data::moshi_component::lm && + model.moshi_lm.n_q > 0 && model.moshi_lm.dep_q > 0 && + model.moshi_lm.dep_q <= model.moshi_lm.n_q && + model.moshi_lm.text_card > 0 && model.moshi_lm.card > 0 && + model.moshi_lm.dim > 0; + } +}; + +struct guard_bind_contract_invalid { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_bind_contract_valid{}(runtime_ev, ctx); + } +}; + +struct guard_step_model_matches { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return ctx.session.model == &runtime_ev.request.model; + } +}; + +struct guard_step_model_mismatch { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_step_model_matches{}(runtime_ev, ctx); + } +}; + +struct guard_step_shape_valid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.request.input_sequence.data() != nullptr && + runtime_ev.request.input_sequence.size() == + static_cast(ctx.session.codebook_count) && + runtime_ev.request.audio_tokens_out.data() != nullptr && + runtime_ev.request.audio_tokens_out.size() >= + static_cast(ctx.session.dep_q); + } +}; + +struct guard_step_shape_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_step_shape_valid{}(runtime_ev, ctx); + } +}; + +struct guard_external_input_embedding_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.request.input_embedding.data() != nullptr && + runtime_ev.request.input_embedding.size() == + static_cast(ctx.session.hidden_dim) && + ctx.session.hidden_dim > 0 && + static_cast(ctx.session.hidden_dim) <= + detail::k_max_hidden_dim; + } +}; + +struct guard_token_input_embedding_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const auto *text_emb = detail::find_tensor(model, "lm.text_emb.weight"); + const bool root_tensors_ok = + detail::tensor_shape(text_emb, hidden_dim, lm.text_card + 1) && + detail::supported_get_rows_dtype( + static_cast(text_emb->type)); + bool audio_tensors_ok = true; + for (int32_t index = 0; index < lm.n_q; ++index) { + const auto *audio_emb = + detail::find_indexed_tensor(model, "lm.emb.%d.weight", index); + audio_tensors_ok = + audio_tensors_ok && + detail::tensor_shape(audio_emb, hidden_dim, lm.card + 1) && + detail::supported_get_rows_dtype( + static_cast(audio_emb->type)); + } + bool tokens_ok = + runtime_ev.request.input_sequence[0] != detail::k_token_zero && + detail::token_in_embedding_range(runtime_ev.request.input_sequence[0], + lm.text_card); + for (int32_t index = 0; index < lm.n_q; ++index) { + tokens_ok = + tokens_ok && + detail::token_in_embedding_range( + runtime_ev.request.input_sequence[static_cast(index + 1)], + lm.card); + } + return runtime_ev.request.input_embedding.data() == nullptr && + !lm.demux_second_stream && hidden_dim > 0 && + static_cast(hidden_dim) <= detail::k_max_hidden_dim && + root_tensors_ok && audio_tensors_ok && tokens_ok; + } +}; + +struct guard_input_embedding_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_external_input_embedding_supported{}(runtime_ev, ctx) || + guard_token_input_embedding_supported{}(runtime_ev, ctx); + } +}; + +struct guard_input_embedding_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_input_embedding_supported{}(runtime_ev, ctx); + } +}; + +struct guard_token_input_embedding_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_external_input_embedding_supported{}(runtime_ev, ctx) && + !guard_token_input_embedding_supported{}(runtime_ev, ctx); + } +}; + +struct guard_input_text_embedding_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.input_text_embedding_ok; + } +}; + +struct guard_input_text_embedding_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_input_text_embedding_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_embedding_view_bound { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.embedding_view_bound; + } +}; + +struct guard_embedding_view_bind_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_embedding_view_bound{}(runtime_ev, ctx); + } +}; + +struct guard_embedding_row_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.embedding_row_ok; + } +}; + +struct guard_embedding_row_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_embedding_row_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_projection_view_bound { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.projection_view_bound; + } +}; + +struct guard_projection_view_bind_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_projection_view_bound{}(runtime_ev, ctx); + } +}; + +struct guard_current_input_audio_token_present { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t index = runtime_ev.ctx.input_audio_codebook_index; + if (index < 0 || index >= lm.n_q) { + return false; + } + const int32_t token = + runtime_ev.request.input_sequence[static_cast(index + 1)]; + return token != detail::k_token_zero && + detail::token_in_embedding_range(token, lm.card) && + guard_input_embedding_supported{}(runtime_ev, ctx); + } +}; + +struct guard_current_input_audio_token_zero { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t index = runtime_ev.ctx.input_audio_codebook_index; + if (index < 0 || index >= lm.n_q) { + return false; + } + return runtime_ev.request.input_sequence[static_cast(index + 1)] == + detail::k_token_zero && + guard_input_embedding_supported{}(runtime_ev, ctx); + } +}; + +struct guard_current_input_audio_token_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_current_input_audio_token_present{}(runtime_ev, ctx) && + !guard_current_input_audio_token_zero{}(runtime_ev, ctx); + } +}; + +struct guard_input_audio_embedding_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.input_audio_embedding_ok; + } +}; + +struct guard_input_audio_embedding_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_input_audio_embedding_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_more_input_audio_codebooks { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.input_audio_embedding_ok && + runtime_ev.ctx.input_audio_codebook_index + 1 < + runtime_ev.request.model.moshi_lm.n_q; + } +}; + +struct guard_input_audio_codebooks_complete { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.ctx.input_audio_embedding_ok && + !guard_more_input_audio_codebooks{}(runtime_ev, ctx); + } +}; + +struct guard_input_embedding_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.input_embedding_ok; + } +}; + +struct guard_input_embedding_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_input_embedding_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_kv_binding_present { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + (void)runtime_ev; + return ctx.temporal_kv.cache != nullptr && ctx.temporal_kv.bind != nullptr; + } +}; + +struct guard_temporal_kv_binding_missing { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_kv_binding_present{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_kv_bound { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &view = runtime_ev.ctx.temporal_kv; + return runtime_ev.ctx.temporal_kv_bound && !view.key_cache.empty() && + !view.value_cache.empty() && !view.layer_cache_offsets.empty() && + view.layer_count > 0 && view.position_capacity > 0 && + view.block_tokens > 0 && view.kv_dim > 0; + } +}; + +struct guard_temporal_kv_bind_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_kv_bound{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_norm_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *norm1 = + detail::find_lm_transformer_tensor(model, layer, "norm1.alpha"); + return layer >= 0 && layer < model.moshi_lm.num_layers && hidden_dim > 0 && + static_cast(hidden_dim) <= detail::k_max_hidden_dim && + detail::tensor_shape(norm1, hidden_dim) && + static_cast(norm1->type) == detail::dtype::f32; + } +}; + +struct guard_temporal_layer_norm_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_norm_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_norm_rms_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_norm_rms_ok; + } +}; + +struct guard_temporal_layer_norm_rms_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_norm_rms_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_norm_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_norm_ok; + } +}; + +struct guard_temporal_layer_norm_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_norm_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_projection_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *projection = + detail::find_lm_transformer_projection(model, layer); + return layer >= 0 && layer < model.moshi_lm.num_layers && hidden_dim > 0 && + static_cast(hidden_dim) <= detail::k_max_hidden_dim && + static_cast(hidden_dim) * 3u <= detail::k_max_qkv_dim && + detail::tensor_shape(projection, hidden_dim, hidden_dim * 3) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } +}; + +struct guard_temporal_layer_projection_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_projection_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_projection_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_projection_ok; + } +}; + +struct guard_temporal_layer_projection_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_projection_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_rope_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t logical_position = detail::current_logical_position( + runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id); + const int32_t physical_position = detail::physical_position( + runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, + logical_position); + const int32_t head_dim = lm.num_heads > 0 ? hidden_dim / lm.num_heads : 0; + return runtime_ev.ctx.temporal_layer_projection_ok && hidden_dim > 0 && + lm.num_heads > 0 && lm.max_period > 0 && + hidden_dim % lm.num_heads == 0 && head_dim > 0 && + (head_dim % 2) == 0 && + static_cast(head_dim) <= detail::k_max_hidden_dim && + logical_position >= 0 && physical_position >= 0 && + physical_position < runtime_ev.ctx.temporal_kv.position_capacity; + } +}; + +struct guard_temporal_layer_rope_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_rope_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_rope_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_rope_ok; + } +}; + +struct guard_temporal_layer_rope_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_rope_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_cache_write_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &view = runtime_ev.ctx.temporal_kv; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + if (!runtime_ev.ctx.temporal_layer_rope_ok || hidden_dim <= 0 || + view.kv_dim != hidden_dim || layer < 0 || layer >= view.layer_count || + view.layer_cache_offsets.empty() || + static_cast(layer) >= view.layer_cache_offsets.size() || + runtime_ev.ctx.temporal_physical_position < 0) { + return false; + } + const size_t layer_offset = + view.layer_cache_offsets[static_cast(layer)]; + const size_t physical_position = + static_cast(runtime_ev.ctx.temporal_physical_position); + const size_t dim = static_cast(hidden_dim); + const size_t begin = layer_offset + physical_position * dim; + const size_t end = begin + dim; + return physical_position < static_cast(view.position_capacity) && + end <= view.key_cache.size() && end <= view.value_cache.size(); + } +}; + +struct guard_temporal_layer_cache_write_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_cache_write_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_cache_write_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_cache_write_ok; + } +}; + +struct guard_temporal_layer_cache_write_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_cache_write_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_attention_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &snapshot = runtime_ev.request.memory_snapshot; + const auto &view = runtime_ev.ctx.temporal_kv; + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t sequence_length = + snapshot.sequence_length(runtime_ev.request.sequence_id); + const int32_t capacity = view.position_capacity; + const int32_t head_dim = lm.num_heads > 0 ? hidden_dim / lm.num_heads : 0; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + if (!runtime_ev.ctx.temporal_layer_cache_write_ok || hidden_dim <= 0 || + lm.num_heads <= 0 || hidden_dim % lm.num_heads != 0 || head_dim <= 0 || + static_cast(head_dim) > detail::k_max_hidden_dim || + sequence_length <= 0 || capacity <= 0 || + static_cast(capacity) > + detail::k_max_temporal_context || + view.kv_dim != hidden_dim || layer < 0 || layer >= view.layer_count || + view.layer_cache_offsets.empty() || + static_cast(layer) >= view.layer_cache_offsets.size()) { + return false; + } + const size_t layer_offset = + view.layer_cache_offsets[static_cast(layer)]; + const size_t dim = static_cast(hidden_dim); + const int32_t logical_begin = + sequence_length > capacity ? sequence_length - capacity : 0; + for (int32_t logical = logical_begin; logical < sequence_length; ++logical) { + const int32_t physical = detail::physical_position( + snapshot, runtime_ev.request.sequence_id, logical); + if (physical < 0 || + physical >= capacity) { + return false; + } + const size_t begin = layer_offset + static_cast(physical) * dim; + const size_t end = begin + dim; + if (end > view.key_cache.size() || end > view.value_cache.size()) { + return false; + } + } + return true; + } +}; + +struct guard_temporal_layer_attention_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_attention_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_attention_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_attention_ok; + } +}; + +struct guard_temporal_layer_attention_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_attention_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_out_projection_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *projection = detail::find_lm_transformer_tensor( + runtime_ev.request.model, layer, "self_attn.out_projs.0.weight"); + return runtime_ev.ctx.temporal_layer_attention_ok && layer >= 0 && + layer < runtime_ev.request.model.moshi_lm.num_layers && + hidden_dim > 0 && + detail::tensor_shape(projection, hidden_dim, hidden_dim) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } +}; + +struct guard_temporal_layer_out_projection_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_out_projection_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_out_projection_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_out_projection_ok; + } +}; + +struct guard_temporal_layer_out_projection_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_out_projection_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_residual_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_residual_ok; + } +}; + +struct guard_temporal_layer_residual_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_residual_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_norm2_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *norm2 = + detail::find_lm_transformer_tensor(model, layer, "norm2.alpha"); + return runtime_ev.ctx.temporal_layer_residual_ok && layer >= 0 && + layer < model.moshi_lm.num_layers && hidden_dim > 0 && + static_cast(hidden_dim) <= detail::k_max_hidden_dim && + detail::tensor_shape(norm2, hidden_dim) && + static_cast(norm2->type) == detail::dtype::f32; + } +}; + +struct guard_temporal_layer_norm2_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_norm2_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_norm2_rms_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_norm2_rms_ok; + } +}; + +struct guard_temporal_layer_norm2_rms_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_norm2_rms_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_norm2_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_norm2_ok; + } +}; + +struct guard_temporal_layer_norm2_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_norm2_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_gating_in_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *linear_in = detail::find_lm_transformer_tensor( + runtime_ev.request.model, layer, "gating.linear_in.weight"); + int64_t projection_dim = 0; + if (linear_in != nullptr && linear_in->n_dims > 1) { + projection_dim = linear_in->dims[1]; + } + return runtime_ev.ctx.temporal_layer_norm2_ok && layer >= 0 && + layer < runtime_ev.request.model.moshi_lm.num_layers && + hidden_dim > 0 && projection_dim > 0 && (projection_dim % 2) == 0 && + static_cast(projection_dim) <= + detail::k_max_gating_projection_dim && + detail::tensor_shape(linear_in, hidden_dim, projection_dim) && + detail::supported_mul_mat_dtype( + static_cast(linear_in->type)); + } +}; + +struct guard_temporal_layer_gating_in_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_gating_in_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_gating_in_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_gating_in_ok; + } +}; + +struct guard_temporal_layer_gating_in_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_gating_in_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_silu_gate_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto *linear_in = detail::find_lm_transformer_tensor( + runtime_ev.request.model, runtime_ev.ctx.temporal_layer_index, + "gating.linear_in.weight"); + int64_t projection_dim = 0; + if (linear_in != nullptr && linear_in->n_dims > 1) { + projection_dim = linear_in->dims[1]; + } + const int64_t gate_dim = projection_dim / 2; + return runtime_ev.ctx.temporal_layer_gating_in_ok && + runtime_ev.ctx.temporal_layer_index >= 0 && + runtime_ev.ctx.temporal_layer_index < + runtime_ev.request.model.moshi_lm.num_layers && + gate_dim > 0 && + static_cast(gate_dim) <= detail::k_max_gating_dim; + } +}; + +struct guard_temporal_layer_silu_gate_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_silu_gate_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_silu_gate_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_silu_gate_ok; + } +}; + +struct guard_temporal_layer_silu_gate_silu_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_silu_gate_silu_ok; + } +}; + +struct guard_temporal_layer_silu_gate_silu_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_silu_gate_silu_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_silu_gate_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_silu_gate_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_gating_out_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t layer = runtime_ev.ctx.temporal_layer_index; + const auto *linear_in = detail::find_lm_transformer_tensor( + runtime_ev.request.model, layer, "gating.linear_in.weight"); + const auto *linear_out = detail::find_lm_transformer_tensor( + runtime_ev.request.model, layer, "gating.linear_out.weight"); + int64_t projection_dim = 0; + if (linear_in != nullptr && linear_in->n_dims > 1) { + projection_dim = linear_in->dims[1]; + } + const int64_t gate_dim = projection_dim / 2; + return runtime_ev.ctx.temporal_layer_silu_gate_ok && layer >= 0 && + layer < runtime_ev.request.model.moshi_lm.num_layers && + hidden_dim > 0 && gate_dim > 0 && + static_cast(gate_dim) <= detail::k_max_gating_dim && + detail::tensor_shape(linear_out, gate_dim, hidden_dim) && + detail::supported_mul_mat_dtype( + static_cast(linear_out->type)); + } +}; + +struct guard_temporal_layer_gating_out_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_gating_out_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_gating_out_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_gating_out_ok; + } +}; + +struct guard_temporal_layer_gating_out_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_gating_out_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_layer_ff_residual_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_ff_residual_ok; + } +}; + +struct guard_temporal_layer_ff_residual_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_layer_ff_residual_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_more_temporal_layers { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_layer_ff_residual_ok && + runtime_ev.ctx.temporal_layer_index + 1 < + runtime_ev.request.model.moshi_lm.num_layers; + } +}; + +struct guard_temporal_layers_complete { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.ctx.temporal_layer_ff_residual_ok && + !guard_more_temporal_layers{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_out_norm_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + const auto *out_norm = + detail::find_tensor(runtime_ev.request.model, "lm.out_norm.alpha"); + return guard_temporal_layers_complete{}(runtime_ev, ctx) && + hidden_dim > 0 && + static_cast(hidden_dim) <= detail::k_max_hidden_dim && + detail::tensor_shape(out_norm, hidden_dim) && + static_cast(out_norm->type) == detail::dtype::f32; + } +}; + +struct guard_temporal_out_norm_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_out_norm_supported{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_out_norm_rms_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_out_norm_rms_ok; + } +}; + +struct guard_temporal_out_norm_rms_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_out_norm_rms_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_temporal_out_norm_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_out_norm_ok; + } +}; + +struct guard_temporal_out_norm_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_out_norm_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_text_logits_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const auto *text_linear = + detail::find_tensor(runtime_ev.request.model, "lm.text_linear.weight"); + return runtime_ev.ctx.temporal_out_norm_ok && hidden_dim > 0 && + lm.text_card > 0 && + detail::tensor_shape(text_linear, hidden_dim, lm.text_card) && + detail::supported_argmax_dtype( + static_cast(text_linear->type)); + } +}; + +struct guard_text_logits_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_text_logits_supported{}(runtime_ev, ctx); + } +}; + +struct guard_forced_text_token_valid { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.forced_text_token >= 0 && + detail::token_in_embedding_range( + runtime_ev.request.forced_text_token, + runtime_ev.request.model.moshi_lm.text_card); + } +}; + +struct guard_forced_text_token_absent { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_forced_text_token_valid{}(runtime_ev, ctx); + } +}; + +struct guard_text_sampling_config_valid { + bool operator()(const event::step_run &, + const action::context &ctx) const noexcept { + return ctx.sampling.enabled && ctx.sampling.text_temperature > 0.0f && + ctx.sampling.text_top_k > 0 && + static_cast(ctx.session.text_card) <= + detail::k_max_sampling_card && + static_cast(ctx.sampling.text_top_k) <= + detail::k_max_sampling_top_k; + } +}; + +struct guard_text_sampling_config_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return ctx.sampling.enabled && ctx.sampling.text_temperature > 0.0f && + !guard_text_sampling_config_valid{}(runtime_ev, ctx); + } +}; + +struct guard_forced_text_token_valid_and_sampling_consume { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_forced_text_token_valid{}(runtime_ev, ctx) && + ctx.sampling.consume_forced_text && + guard_text_sampling_config_valid{}(runtime_ev, ctx); + } +}; + +struct guard_forced_text_token_valid_without_sampling_consume { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_forced_text_token_valid{}(runtime_ev, ctx) && + (!ctx.sampling.consume_forced_text || !ctx.sampling.enabled || + ctx.sampling.text_temperature <= 0.0f); + } +}; + +struct guard_forced_text_sampling_config_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_forced_text_token_valid{}(runtime_ev, ctx) && + ctx.sampling.consume_forced_text && + guard_text_sampling_config_invalid{}(runtime_ev, ctx); + } +}; + +struct guard_text_logits_projection_bound_and_no_forced_token { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_projection_view_bound{}(runtime_ev, ctx) && + guard_forced_text_token_absent{}(runtime_ev, ctx); + } +}; + +struct guard_text_logits_projection_bound_and_no_forced_token_argmax { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_text_logits_projection_bound_and_no_forced_token{}(runtime_ev, + ctx) && + (!ctx.sampling.enabled || ctx.sampling.text_temperature <= 0.0f); + } +}; + +struct guard_text_logits_projection_bound_and_no_forced_token_sampling { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_text_logits_projection_bound_and_no_forced_token{}(runtime_ev, + ctx) && + guard_text_sampling_config_valid{}(runtime_ev, ctx); + } +}; + +struct guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_text_logits_projection_bound_and_no_forced_token{}(runtime_ev, + ctx) && + guard_text_sampling_config_invalid{}(runtime_ev, ctx); + } +}; + +struct guard_text_logits_matmul_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.text_logits_ok; + } +}; + +struct guard_text_logits_matmul_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_text_logits_matmul_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_text_logits_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.text_logits_ok && runtime_ev.ctx.best_index >= 0; + } +}; + +struct guard_text_logits_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_text_logits_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_kv_binding_present { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + (void)runtime_ev; + return ctx.depformer_kv.cache != nullptr && + ctx.depformer_kv.bind != nullptr; + } +}; + +struct guard_depformer_kv_binding_missing { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_kv_binding_present{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_kv_bound { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &view = runtime_ev.ctx.depformer_kv; + return runtime_ev.ctx.depformer_kv_bound && !view.key_cache.empty() && + !view.value_cache.empty() && !view.layer_cache_offsets.empty() && + view.offset != nullptr && *view.offset >= 0 && + view.layer_count > 0 && view.position_capacity > 0 && + view.kv_dim > 0; + } +}; + +struct guard_depformer_kv_bind_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_kv_bound{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_scheduled_weight_present { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + if (lm.depformer_weight_schedule_count == 0u || codebook < 0 || + static_cast(codebook) >= + lm.depformer_weight_schedule_count) { + return false; + } + const int32_t weight_index = + lm.depformer_weight_schedule[static_cast(codebook)]; + return weight_index >= 0 && weight_index < lm.dep_q; + } +}; + +struct guard_depformer_scheduled_weight_absent { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.model.moshi_lm.depformer_weight_schedule_count == + 0u; + } +}; + +struct guard_depformer_scheduled_weight_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_scheduled_weight_absent{}(runtime_ev, ctx) && + !guard_depformer_scheduled_weight_present{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_text_input_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + if (codebook != 0) { + return false; + } + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t dep_dim = lm.depformer_dim; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return false; + } + const auto *input_projection = detail::find_indexed_tensor( + model, "lm.depformer_in.%d.weight", weight_index); + const auto *embedding = + detail::find_tensor(model, "lm.depformer_text_emb.weight"); + return runtime_ev.ctx.depformer_kv_bound && runtime_ev.ctx.text_logits_ok && + codebook == 0 && hidden_dim > 0 && dep_dim > 0 && + static_cast(dep_dim) <= detail::k_max_hidden_dim && + detail::tensor_shape(input_projection, hidden_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(input_projection->type)) && + detail::tensor_shape(embedding, dep_dim, lm.text_card + 1) && + detail::supported_get_rows_dtype( + static_cast(embedding->type)) && + detail::token_in_embedding_range(runtime_ev.request.text_token_out, + lm.text_card); + } +}; + +struct guard_depformer_audio_input_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + if (codebook <= 0 || codebook >= lm.dep_q) { + return false; + } + const int32_t hidden_dim = ctx.session.hidden_dim; + const int32_t dep_dim = lm.depformer_dim; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return false; + } + const auto *input_projection = detail::find_indexed_tensor( + model, "lm.depformer_in.%d.weight", weight_index); + const auto *embedding = detail::find_indexed_tensor( + model, "lm.depformer_emb.%d.weight", codebook - 1); + return runtime_ev.ctx.depformer_kv_bound && runtime_ev.ctx.text_logits_ok && + codebook > 0 && codebook < lm.dep_q && hidden_dim > 0 && + dep_dim > 0 && + static_cast(dep_dim) <= detail::k_max_hidden_dim && + detail::tensor_shape(input_projection, hidden_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(input_projection->type)) && + detail::tensor_shape(embedding, dep_dim, lm.card + 1) && + detail::supported_get_rows_dtype( + static_cast(embedding->type)) && + detail::token_in_embedding_range( + runtime_ev.request + .audio_tokens_out[static_cast(codebook - 1)], + lm.card); + } +}; + +struct guard_depformer_input_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_text_input_supported{}(runtime_ev, ctx) && + !guard_depformer_audio_input_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_input_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_input_ok; + } +}; + +struct guard_depformer_input_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_input_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_input_projection_bound { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_input_projection_bound; + } +}; + +struct guard_depformer_input_projection_bind_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_input_projection_bound{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_input_projection_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_input_projection_ok; + } +}; + +struct guard_depformer_input_projection_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_input_projection_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_text_input_projection_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_depformer_input_projection_succeeded{}(runtime_ev, ctx) && + guard_depformer_text_input_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_audio_input_projection_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_depformer_input_projection_succeeded{}(runtime_ev, ctx) && + guard_depformer_audio_input_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_input_projection_embedding_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_depformer_input_projection_succeeded{}(runtime_ev, ctx) && + !guard_depformer_text_input_supported{}(runtime_ev, ctx) && + !guard_depformer_audio_input_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_norm_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const auto *norm1 = + detail::find_depformer_tensor(model, layer, "norm1.alpha"); + return runtime_ev.ctx.depformer_input_ok && layer >= 0 && + layer < model.moshi_lm.depformer_num_layers && dep_dim > 0 && + static_cast(dep_dim) <= detail::k_max_hidden_dim && + detail::tensor_shape(norm1, dep_dim) && + static_cast(norm1->type) == detail::dtype::f32; + } +}; + +struct guard_depformer_layer_norm_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_norm_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_norm_rms_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_norm_rms_ok; + } +}; + +struct guard_depformer_layer_norm_rms_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_norm_rms_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_norm_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_norm_ok; + } +}; + +struct guard_depformer_layer_norm_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_norm_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_projection_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return false; + } + const auto *projection = + detail::find_depformer_projection(model, layer, weight_index); + return runtime_ev.ctx.depformer_layer_norm_ok && layer >= 0 && + layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && + codebook < model.moshi_lm.dep_q && dep_dim > 0 && + static_cast(dep_dim) * 3u <= detail::k_max_qkv_dim && + detail::tensor_shape(projection, dep_dim, dep_dim * 3) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } +}; + +struct guard_depformer_layer_projection_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_projection_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_projection_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_projection_ok; + } +}; + +struct guard_depformer_layer_projection_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_projection_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_cache_write_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &view = runtime_ev.ctx.depformer_kv; + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + if (!runtime_ev.ctx.depformer_layer_projection_ok || + view.offset == nullptr || *view.offset < 0 || dep_dim <= 0 || + view.kv_dim != dep_dim || layer < 0 || layer >= view.layer_count || + view.layer_cache_offsets.empty() || + static_cast(layer) >= view.layer_cache_offsets.size() || + view.position_capacity <= 0) { + return false; + } + const int32_t physical = *view.offset % view.position_capacity; + const size_t layer_offset = + view.layer_cache_offsets[static_cast(layer)]; + const size_t begin = layer_offset + static_cast(physical) * + static_cast(dep_dim); + const size_t end = begin + static_cast(dep_dim); + return end <= view.key_cache.size() && end <= view.value_cache.size(); + } +}; + +struct guard_depformer_layer_cache_write_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_cache_write_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_cache_write_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_cache_write_ok; + } +}; + +struct guard_depformer_layer_cache_write_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_cache_write_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_attention_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const auto &view = runtime_ev.ctx.depformer_kv; + const int32_t dep_dim = lm.depformer_dim; + const int32_t head_dim = + lm.depformer_num_heads > 0 ? dep_dim / lm.depformer_num_heads : 0; + const int32_t valid_positions = runtime_ev.ctx.depformer_valid_positions; + const int32_t capacity = view.position_capacity; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + if (!runtime_ev.ctx.depformer_layer_cache_write_ok || dep_dim <= 0 || + lm.depformer_num_heads <= 0 || dep_dim % lm.depformer_num_heads != 0 || + head_dim <= 0 || + static_cast(head_dim) > detail::k_max_hidden_dim || + valid_positions <= 0 || capacity <= 0 || + static_cast(capacity) > detail::k_max_depformer_context || + valid_positions > capacity || view.kv_dim != dep_dim || layer < 0 || + layer >= view.layer_count || view.layer_cache_offsets.empty() || + static_cast(layer) >= view.layer_cache_offsets.size()) { + return false; + } + const size_t layer_offset = + view.layer_cache_offsets[static_cast(layer)]; + const size_t dim = static_cast(dep_dim); + for (int32_t physical = 0; physical < capacity; ++physical) { + const size_t begin = layer_offset + static_cast(physical) * dim; + const size_t end = begin + dim; + if (end > view.key_cache.size() || end > view.value_cache.size()) { + return false; + } + } + return true; + } +}; + +struct guard_depformer_layer_attention_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_attention_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_attention_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_attention_ok; + } +}; + +struct guard_depformer_layer_attention_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_attention_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_out_projection_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return false; + } + const auto *projection = detail::find_depformer_codebook_tensor( + model, layer, "self_attn.out_projs.%d.weight", weight_index); + return runtime_ev.ctx.depformer_layer_attention_ok && layer >= 0 && + layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && + codebook < model.moshi_lm.dep_q && dep_dim > 0 && + detail::tensor_shape(projection, dep_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } +}; + +struct guard_depformer_layer_out_projection_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_out_projection_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_out_projection_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_out_projection_ok; + } +}; + +struct guard_depformer_layer_out_projection_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_out_projection_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_residual_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_residual_ok; + } +}; + +struct guard_depformer_layer_residual_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_residual_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_norm2_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + const int32_t dep_dim = model.moshi_lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const auto *norm2 = + detail::find_depformer_tensor(model, layer, "norm2.alpha"); + return runtime_ev.ctx.depformer_layer_residual_ok && layer >= 0 && + layer < model.moshi_lm.depformer_num_layers && dep_dim > 0 && + static_cast(dep_dim) <= detail::k_max_hidden_dim && + detail::tensor_shape(norm2, dep_dim) && + static_cast(norm2->type) == detail::dtype::f32; + } +}; + +struct guard_depformer_layer_norm2_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_norm2_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_norm2_rms_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_norm2_rms_ok; + } +}; + +struct guard_depformer_layer_norm2_rms_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_norm2_rms_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_norm2_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_norm2_ok; + } +}; + +struct guard_depformer_layer_norm2_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_norm2_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_gating_in_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return false; + } + const auto *linear_in = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_in.weight", weight_index); + int64_t projection_dim = 0; + if (linear_in != nullptr && linear_in->n_dims > 1) { + projection_dim = linear_in->dims[1]; + } + return runtime_ev.ctx.depformer_layer_norm2_ok && layer >= 0 && + layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && + codebook < model.moshi_lm.dep_q && dep_dim > 0 && + projection_dim > 0 && (projection_dim % 2) == 0 && + static_cast(projection_dim) <= + detail::k_max_gating_projection_dim && + detail::tensor_shape(linear_in, dep_dim, projection_dim) && + detail::supported_mul_mat_dtype( + static_cast(linear_in->type)); + } +}; + +struct guard_depformer_layer_gating_in_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_gating_in_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_gating_in_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_gating_in_ok; + } +}; + +struct guard_depformer_layer_gating_in_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_gating_in_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_silu_gate_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + if (weight_index < 0 || weight_index >= lm.dep_q || codebook < 0 || + codebook >= lm.dep_q) { + return false; + } + const auto *linear_in = detail::find_depformer_codebook_tensor( + runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, + "gating.%d.linear_in.weight", weight_index); + int64_t projection_dim = 0; + if (linear_in != nullptr && linear_in->n_dims > 1) { + projection_dim = linear_in->dims[1]; + } + const int64_t gate_dim = projection_dim / 2; + return runtime_ev.ctx.depformer_layer_gating_in_ok && + runtime_ev.ctx.depformer_layer_index >= 0 && + runtime_ev.ctx.depformer_layer_index < + runtime_ev.request.model.moshi_lm.depformer_num_layers && + gate_dim > 0 && + static_cast(gate_dim) <= detail::k_max_gating_dim; + } +}; + +struct guard_depformer_layer_silu_gate_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_silu_gate_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_silu_gate_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_silu_gate_ok; + } +}; + +struct guard_depformer_layer_silu_gate_silu_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_silu_gate_silu_ok; + } +}; + +struct guard_depformer_layer_silu_gate_silu_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_silu_gate_silu_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_silu_gate_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_silu_gate_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_gating_out_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t layer = runtime_ev.ctx.depformer_layer_index; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return false; + } + const auto *linear_in = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_in.weight", weight_index); + const auto *linear_out = detail::find_depformer_codebook_tensor( + model, layer, "gating.%d.linear_out.weight", weight_index); + int64_t projection_dim = 0; + if (linear_in != nullptr && linear_in->n_dims > 1) { + projection_dim = linear_in->dims[1]; + } + const int64_t gate_dim = projection_dim / 2; + return runtime_ev.ctx.depformer_layer_silu_gate_ok && layer >= 0 && + layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && + codebook < model.moshi_lm.dep_q && dep_dim > 0 && gate_dim > 0 && + static_cast(gate_dim) <= detail::k_max_gating_dim && + detail::tensor_shape(linear_out, gate_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(linear_out->type)); + } +}; + +struct guard_depformer_layer_gating_out_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_gating_out_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_gating_out_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_gating_out_ok; + } +}; + +struct guard_depformer_layer_gating_out_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_gating_out_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_layer_ff_residual_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_ff_residual_ok; + } +}; + +struct guard_depformer_layer_ff_residual_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_layer_ff_residual_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_more_depformer_layers { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_layer_ff_residual_ok && + runtime_ev.ctx.depformer_layer_index + 1 < + runtime_ev.request.model.moshi_lm.depformer_num_layers; + } +}; + +struct guard_depformer_layers_complete { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.ctx.depformer_layer_ff_residual_ok && + !guard_more_depformer_layers{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_supported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; + const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; + const auto *linear = + detail::find_indexed_tensor(model, "lm.linears.%d.weight", codebook); + return guard_depformer_layers_complete{}(runtime_ev, ctx) && + codebook >= 0 && codebook < lm.dep_q && dep_dim > 0 && lm.card > 0 && + detail::tensor_shape(linear, dep_dim, lm.card) && + detail::supported_argmax_dtype( + static_cast(linear->type)); + } +}; + +struct guard_depformer_logits_unsupported { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_logits_supported{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_logits_ok && + runtime_ev.ctx.best_index >= 0 && + runtime_ev.ctx.best_index < runtime_ev.request.model.moshi_lm.card; + } +}; + +struct guard_depformer_logits_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_logits_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_sampling_config_valid { + bool operator()(const event::step_run &, + const action::context &ctx) const noexcept { + return ctx.sampling.enabled && ctx.sampling.audio_temperature > 0.0f && + ctx.sampling.audio_top_k > 0 && + static_cast(ctx.session.audio_card) <= + detail::k_max_sampling_card && + static_cast(ctx.sampling.audio_top_k) <= + detail::k_max_sampling_top_k; + } +}; + +struct guard_depformer_sampling_config_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return ctx.sampling.enabled && ctx.sampling.audio_temperature > 0.0f && + !guard_depformer_sampling_config_valid{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_argmax { + bool operator()(const event::step_run &, + const action::context &ctx) const noexcept { + return !ctx.sampling.enabled || ctx.sampling.audio_temperature <= 0.0f; + } +}; + +struct guard_depformer_logits_sampling { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_depformer_sampling_config_valid{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_sampling_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_depformer_sampling_config_invalid{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_projection_bound_argmax { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_projection_view_bound{}(runtime_ev, ctx) && + guard_depformer_logits_argmax{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_projection_bound_sampling { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_projection_view_bound{}(runtime_ev, ctx) && + guard_depformer_logits_sampling{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_projection_bound_sampling_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_projection_view_bound{}(runtime_ev, ctx) && + guard_depformer_logits_sampling_invalid{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_logits_matmul_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_logits_ok; + } +}; + +struct guard_depformer_logits_matmul_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_logits_matmul_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_more_depformer_codebooks { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_logits_ok && + runtime_ev.ctx.depformer_codebook_index + 1 < + runtime_ev.request.model.moshi_lm.dep_q; + } +}; + +struct guard_depformer_codebooks_complete { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.ctx.depformer_logits_ok && + !guard_more_depformer_codebooks{}(runtime_ev, ctx); + } +}; + +template struct guard_has_error_out { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.error_out != nullptr; + } +}; + +template struct guard_no_error_out { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_error_out{}(runtime_ev, ctx); + } +}; + +struct guard_has_initialize_done_callback { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return static_cast(runtime_ev.request.on_done); + } +}; + +struct guard_no_initialize_done_callback { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_initialize_done_callback{}(runtime_ev, ctx); + } +}; + +struct guard_has_initialize_error_callback { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return static_cast(runtime_ev.request.on_error); + } +}; + +struct guard_no_initialize_error_callback { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_initialize_error_callback{}(runtime_ev, ctx); + } +}; + +struct guard_unexpected_error_out_present { + template + bool operator()(const event_type &ev, + const action::context &) const noexcept { + if constexpr (requires { + ev.ctx.err; + ev.request.error_out; + }) { + return ev.request.error_out != nullptr; + } else { + return false; + } + } +}; + +struct guard_unexpected_error_out_absent { + template + bool operator()(const event_type &ev, + const action::context &ctx) const noexcept { + return !guard_unexpected_error_out_present{}(ev, ctx); + } +}; + +} // namespace emel::speech::generator::moshi::executor::guard diff --git a/src/emel/speech/generator/moshi/executor/sm.hpp b/src/emel/speech/generator/moshi/executor/sm.hpp new file mode 100644 index 00000000..72e198db --- /dev/null +++ b/src/emel/speech/generator/moshi/executor/sm.hpp @@ -0,0 +1,943 @@ +#pragma once + +#include + +#include "emel/sm.hpp" +#include "emel/speech/generator/moshi/executor/actions.hpp" +#include "emel/speech/generator/moshi/executor/context.hpp" +#include "emel/speech/generator/moshi/executor/events.hpp" +#include "emel/speech/generator/moshi/executor/guards.hpp" + +namespace emel::speech::generator::moshi::executor { + +struct state_uninitialized {}; +struct state_bind_contract_decision {}; +struct state_init_error_out_decision {}; +struct state_init_callback_decision {}; +struct state_init_failed_error_out_decision {}; +struct state_init_failed_callback_decision {}; +struct state_ready {}; +struct state_step_model_decision {}; +struct state_step_shape_decision {}; +struct state_step_execution_decision {}; +struct state_input_embedding {}; +struct state_input_text_embedding_bind {}; +struct state_input_text_embedding_bind_result_decision {}; +struct state_input_text_embedding_row {}; +struct state_input_text_embedding_row_result_decision {}; +struct state_input_text_embedding_apply {}; +struct state_input_text_embedding_result_decision {}; +struct state_input_audio_token_decision {}; +struct state_input_audio_embedding {}; +struct state_input_audio_embedding_bind_result_decision {}; +struct state_input_audio_embedding_row {}; +struct state_input_audio_embedding_row_result_decision {}; +struct state_input_audio_embedding_apply {}; +struct state_input_audio_embedding_result_decision {}; +struct state_input_audio_codebook_advance {}; +struct state_input_embedding_result_decision {}; +struct state_bind_temporal_kv {}; +struct state_temporal_kv_result_decision {}; +struct state_temporal_layer_norm {}; +struct state_temporal_layer_norm_rms_result_decision {}; +struct state_temporal_layer_norm_scale {}; +struct state_temporal_layer_norm_result_decision {}; +struct state_temporal_layer_projection {}; +struct state_temporal_layer_projection_bind_result_decision {}; +struct state_temporal_layer_projection_run {}; +struct state_temporal_layer_projection_result_decision {}; +struct state_temporal_layer_rope {}; +struct state_temporal_layer_rope_result_decision {}; +struct state_temporal_layer_cache_write {}; +struct state_temporal_layer_cache_write_result_decision {}; +struct state_temporal_layer_attention {}; +struct state_temporal_layer_attention_result_decision {}; +struct state_temporal_layer_out_projection {}; +struct state_temporal_layer_out_projection_bind_result_decision {}; +struct state_temporal_layer_out_projection_run {}; +struct state_temporal_layer_out_projection_result_decision {}; +struct state_temporal_layer_residual {}; +struct state_temporal_layer_residual_result_decision {}; +struct state_temporal_layer_norm2 {}; +struct state_temporal_layer_norm2_rms_result_decision {}; +struct state_temporal_layer_norm2_scale {}; +struct state_temporal_layer_norm2_result_decision {}; +struct state_temporal_layer_gating_in {}; +struct state_temporal_layer_gating_in_bind_result_decision {}; +struct state_temporal_layer_gating_in_run {}; +struct state_temporal_layer_gating_in_result_decision {}; +struct state_temporal_layer_silu_gate {}; +struct state_temporal_layer_silu_gate_silu_result_decision {}; +struct state_temporal_layer_silu_gate_mul {}; +struct state_temporal_layer_silu_gate_result_decision {}; +struct state_temporal_layer_gating_out {}; +struct state_temporal_layer_gating_out_bind_result_decision {}; +struct state_temporal_layer_gating_out_run {}; +struct state_temporal_layer_gating_out_result_decision {}; +struct state_temporal_layer_ff_residual {}; +struct state_temporal_layer_ff_residual_result_decision {}; +struct state_temporal_layer_advance {}; +struct state_temporal_out_norm {}; +struct state_temporal_out_norm_rms_result_decision {}; +struct state_temporal_out_norm_scale {}; +struct state_temporal_out_norm_result_decision {}; +struct state_text_logits {}; +struct state_text_logits_bind_result_decision {}; +struct state_text_logits_run {}; +struct state_text_logits_sample_projection {}; +struct state_text_logits_sample_projection_result_decision {}; +struct state_text_logits_sample_select {}; +struct state_forced_text_sampling_consume {}; +struct state_forced_text_sampling_result_decision {}; +struct state_text_logits_result_decision {}; +struct state_bind_depformer_kv {}; +struct state_depformer_kv_result_decision {}; +struct state_depformer_weight_decision {}; +struct state_depformer_input {}; +struct state_depformer_input_projection_bind_result_decision {}; +struct state_depformer_input_projection {}; +struct state_depformer_input_projection_result_decision {}; +struct state_depformer_input_embedding_bind {}; +struct state_depformer_input_embedding_bind_result_decision {}; +struct state_depformer_input_embedding_row {}; +struct state_depformer_input_embedding_row_result_decision {}; +struct state_depformer_input_embedding_apply {}; +struct state_depformer_input_result_decision {}; +struct state_depformer_layer_norm {}; +struct state_depformer_layer_norm_rms_result_decision {}; +struct state_depformer_layer_norm_scale {}; +struct state_depformer_layer_norm_result_decision {}; +struct state_depformer_layer_projection {}; +struct state_depformer_layer_projection_bind_result_decision {}; +struct state_depformer_layer_projection_run {}; +struct state_depformer_layer_projection_result_decision {}; +struct state_depformer_layer_cache_write {}; +struct state_depformer_layer_cache_write_result_decision {}; +struct state_depformer_layer_attention {}; +struct state_depformer_layer_attention_result_decision {}; +struct state_depformer_layer_out_projection {}; +struct state_depformer_layer_out_projection_bind_result_decision {}; +struct state_depformer_layer_out_projection_run {}; +struct state_depformer_layer_out_projection_result_decision {}; +struct state_depformer_layer_residual {}; +struct state_depformer_layer_residual_result_decision {}; +struct state_depformer_layer_norm2 {}; +struct state_depformer_layer_norm2_rms_result_decision {}; +struct state_depformer_layer_norm2_scale {}; +struct state_depformer_layer_norm2_result_decision {}; +struct state_depformer_layer_gating_in {}; +struct state_depformer_layer_gating_in_bind_result_decision {}; +struct state_depformer_layer_gating_in_run {}; +struct state_depformer_layer_gating_in_result_decision {}; +struct state_depformer_layer_silu_gate {}; +struct state_depformer_layer_silu_gate_silu_result_decision {}; +struct state_depformer_layer_silu_gate_mul {}; +struct state_depformer_layer_silu_gate_result_decision {}; +struct state_depformer_layer_gating_out {}; +struct state_depformer_layer_gating_out_bind_result_decision {}; +struct state_depformer_layer_gating_out_run {}; +struct state_depformer_layer_gating_out_result_decision {}; +struct state_depformer_layer_ff_residual {}; +struct state_depformer_layer_ff_residual_result_decision {}; +struct state_depformer_layer_advance {}; +struct state_depformer_logits {}; +struct state_depformer_logits_bind_result_decision {}; +struct state_depformer_logits_run {}; +struct state_depformer_logits_sample_projection {}; +struct state_depformer_logits_sample_projection_result_decision {}; +struct state_depformer_logits_sample_select {}; +struct state_depformer_token_publish {}; +struct state_depformer_logits_result_decision {}; +struct state_depformer_codebook_advance {}; +struct state_step_error_out_decision {}; +struct state_uninit_step_error_out_decision {}; + +struct model { + auto operator()() const { + namespace sml = stateforward::sml; + using init_run = event::initialize_run; + using step_run = event::step_run; + + // clang-format off + return sml::make_transition_table( + //------------------------------------------------------------------------------// + // Bind the Moshi LM execution contract. + sml::state <= *sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_bind_contract_valid{} ] + / action::effect_bind_contract{} + , sml::state <= sml::state + + sml::completion [ guard::guard_bind_contract_invalid{} ] + / action::effect_mark_bind_failed{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_initialize_done_callback{} ] + / action::effect_emit_initialize_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_initialize_done_callback{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_initialize_error_callback{} ] + / action::effect_emit_initialize_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_initialize_error_callback{} ] + + //------------------------------------------------------------------------------// + // Graph-step request validation and Moshi LM execution. + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_step_model_matches{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_step_model_mismatch{} ] + / action::effect_mark_model_mismatch{} + , sml::state <= sml::state + + sml::completion [ guard::guard_step_shape_valid{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_step_shape_invalid{} ] + / action::effect_mark_request_shape{} + , sml::state <= sml::state + + sml::completion [ guard::guard_input_embedding_supported{} ] + / action::effect_begin_input_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_input_embedding_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_external_input_embedding_supported{} ] + / action::effect_apply_external_input_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_token_input_embedding_supported{} ] + / action::effect_bind_input_text_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_token_input_embedding_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_view_bound{} ] + / action::effect_run_embedding_row_fetch{} + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_row_succeeded{} ] + / action::effect_apply_input_text_embedding_row{} + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_row_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_input_text_embedding_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_input_text_embedding_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_current_input_audio_token_present{} ] + / action::effect_bind_input_audio_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_current_input_audio_token_zero{} ] + / action::effect_skip_zero_input_audio_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_current_input_audio_token_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_view_bound{} ] + / action::effect_run_embedding_row_fetch{} + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_row_succeeded{} ] + / action::effect_apply_input_audio_embedding_row{} + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_row_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_input_audio_embedding_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_input_audio_embedding_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_more_input_audio_codebooks{} ] + / action::effect_advance_input_audio_codebook{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_input_audio_codebooks_complete{} ] + / action::effect_finish_input_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_input_embedding_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_kv_binding_present{} ] + / action::effect_bind_temporal_kv{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_kv_binding_missing{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_kv_bound{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_kv_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_supported{} ] + / action::effect_run_temporal_layer_norm_rms{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_rms_succeeded{} ] + / action::effect_run_temporal_layer_norm_scale{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_rms_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_projection_supported{} ] + / action::effect_bind_temporal_layer_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_projection_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_temporal_layer_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_projection_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_projection_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_rope_supported{} ] + / action::effect_apply_temporal_layer_rope{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_rope_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_rope_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_rope_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_cache_write_supported{} ] + / action::effect_write_temporal_layer_kv_cache{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_cache_write_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_cache_write_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_cache_write_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_attention_supported{} ] + / action::effect_run_temporal_layer_attention{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_attention_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_attention_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_attention_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_out_projection_supported{} ] + / action::effect_bind_temporal_layer_out_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_out_projection_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_temporal_layer_out_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_out_projection_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_out_projection_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + / action::effect_apply_temporal_layer_attention_residual{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_residual_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_residual_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm2_supported{} ] + / action::effect_run_temporal_layer_norm2_rms{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm2_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm2_rms_succeeded{} ] + / action::effect_run_temporal_layer_norm2_scale{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm2_rms_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm2_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm2_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_in_supported{} ] + / action::effect_bind_temporal_layer_gating_in{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_in_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_temporal_layer_gating_in{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_in_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_in_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_silu_gate_supported{} ] + / action::effect_run_temporal_layer_silu_gate_silu{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_silu_gate_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_silu_gate_silu_succeeded{} ] + / action::effect_run_temporal_layer_silu_gate_mul{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_silu_gate_silu_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_silu_gate_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_silu_gate_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_out_supported{} ] + / action::effect_bind_temporal_layer_gating_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_out_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_temporal_layer_gating_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_out_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_gating_out_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + / action::effect_apply_temporal_layer_ff_residual{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_ff_residual_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_ff_residual_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_more_temporal_layers{} ] + / action::effect_advance_temporal_layer{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layers_complete{} ] + / action::effect_run_temporal_out_norm_rms{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_out_norm_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_supported{} ] + / action::effect_run_temporal_layer_norm_rms{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_norm_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_out_norm_rms_succeeded{} ] + / action::effect_run_temporal_out_norm_scale{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_out_norm_rms_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_out_norm_succeeded{} ] + / action::effect_publish_temporal_out_norm{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_out_norm_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_supported{} ] + / action::effect_bind_text_token_logits{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_forced_text_token_valid_and_sampling_consume{} ] + / action::effect_consume_forced_text_sampling{} + , sml::state <= sml::state + + sml::completion [ guard::guard_forced_text_token_valid_without_sampling_consume{} ] + / action::effect_publish_forced_text_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_forced_text_sampling_config_invalid{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_projection_bound_and_no_forced_token_argmax{} ] + / action::effect_select_text_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_projection_bound_and_no_forced_token_sampling{} ] + / action::effect_compute_text_token_logits{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_matmul_succeeded{} ] + / action::effect_publish_forced_text_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_matmul_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_matmul_succeeded{} ] + / action::effect_sample_text_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_matmul_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_text_logits_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_kv_binding_present{} ] + / action::effect_bind_depformer_kv{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_kv_binding_missing{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_kv_bound{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_kv_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_scheduled_weight_present{} ] + / action::effect_use_depformer_scheduled_weight{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_scheduled_weight_absent{} ] + / action::effect_use_depformer_codebook_weight{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_scheduled_weight_invalid{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_text_input_supported{} ] + / action::effect_bind_depformer_text_input_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_audio_input_supported{} ] + / action::effect_bind_depformer_audio_input_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_input_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_input_projection_bound{} ] + / action::effect_run_depformer_input_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_input_projection_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_text_input_projection_succeeded{} ] + / action::effect_bind_depformer_text_input_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_audio_input_projection_succeeded{} ] + / action::effect_bind_depformer_audio_input_embedding{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_input_projection_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_input_projection_embedding_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_view_bound{} ] + / action::effect_run_embedding_row_fetch{} + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_row_succeeded{} ] + / action::effect_apply_depformer_input_embedding_row{} + , sml::state <= sml::state + + sml::completion [ guard::guard_embedding_row_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_input_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_input_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_supported{} ] + / action::effect_run_depformer_layer_norm_rms{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_rms_succeeded{} ] + / action::effect_run_depformer_layer_norm_scale{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_rms_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_projection_supported{} ] + / action::effect_bind_depformer_layer_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_projection_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_depformer_layer_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_projection_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_projection_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_cache_write_supported{} ] + / action::effect_write_depformer_layer_kv_cache{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_cache_write_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_cache_write_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_cache_write_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_attention_supported{} ] + / action::effect_run_depformer_layer_attention{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_attention_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_attention_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_attention_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_out_projection_supported{} ] + / action::effect_bind_depformer_layer_out_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_out_projection_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_depformer_layer_out_projection{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_out_projection_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_out_projection_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + / action::effect_apply_depformer_layer_attention_residual{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_residual_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_residual_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm2_supported{} ] + / action::effect_run_depformer_layer_norm2_rms{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm2_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm2_rms_succeeded{} ] + / action::effect_run_depformer_layer_norm2_scale{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm2_rms_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm2_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm2_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_in_supported{} ] + / action::effect_bind_depformer_layer_gating_in{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_in_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_depformer_layer_gating_in{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_in_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_in_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_silu_gate_supported{} ] + / action::effect_run_depformer_layer_silu_gate_silu{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_silu_gate_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_silu_gate_silu_succeeded{} ] + / action::effect_run_depformer_layer_silu_gate_mul{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_silu_gate_silu_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_silu_gate_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_silu_gate_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_out_supported{} ] + / action::effect_bind_depformer_layer_gating_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_out_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bound{} ] + / action::effect_run_depformer_layer_gating_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_out_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_gating_out_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + / action::effect_apply_depformer_layer_ff_residual{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_ff_residual_succeeded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_ff_residual_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_more_depformer_layers{} ] + / action::effect_advance_depformer_layer{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_supported{} ] + / action::effect_bind_depformer_token_logits{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_projection_bound_argmax{} ] + / action::effect_select_depformer_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_projection_bound_sampling{} ] + / action::effect_compute_depformer_token_logits{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_projection_bound_sampling_invalid{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_projection_view_bind_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_matmul_succeeded{} ] + / action::effect_sample_depformer_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_matmul_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_supported{} ] + / action::effect_run_depformer_layer_norm_rms{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_layer_norm_unsupported{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_succeeded{} ] + / action::effect_publish_depformer_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_succeeded{} ] + / action::effect_publish_depformer_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_logits_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_more_depformer_codebooks{} ] + / action::effect_advance_depformer_codebook{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_codebooks_complete{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_scheduled_weight_present{} ] + / action::effect_use_depformer_scheduled_weight{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_scheduled_weight_absent{} ] + / action::effect_use_depformer_codebook_weight{} + , sml::state <= sml::state + + sml::completion [ guard::guard_depformer_scheduled_weight_invalid{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + + //------------------------------------------------------------------------------// + // Requests before initialization answer explicitly. + , sml::state <= sml::state + + sml::event + / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + + //------------------------------------------------------------------------------// + // Reset. + , sml::state <= sml::state + + sml::event + / action::effect_reset_session{} + + //------------------------------------------------------------------------------// + // Unexpected events. + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_present{} ] + / action::effect_mark_unexpected_and_store{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_absent{} ] + / action::effect_mark_unexpected{} + ); + // clang-format on + } +}; + +struct sm : public emel::sm { + using base_type = emel::sm; + using base_type::is; + using base_type::visit_current_states; + + sm() = default; + explicit sm(const action::temporal_kv_binding &kv_binding) + : base_type(std::in_place, kv_binding) {} + explicit sm(const action::kv_bindings &kv_binding_set) + : base_type(std::in_place, kv_binding_set) {} + + bool process_event(const event::initialize &ev) { + event::initialize_ctx ctx{}; + event::initialize_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool + process_event(const emel::speech::generator::moshi::event::graph_step &ev) { + event::step_ctx ctx{}; + event::step_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::reset &ev) { + return base_type::process_event(ev); + } +}; + +using Executor = sm; + +} // namespace emel::speech::generator::moshi::executor diff --git a/src/emel/speech/generator/moshi/guards.hpp b/src/emel/speech/generator/moshi/guards.hpp new file mode 100644 index 00000000..3aa3b764 --- /dev/null +++ b/src/emel/speech/generator/moshi/guards.hpp @@ -0,0 +1,686 @@ +#pragma once + +#include "emel/kernel/detail.hpp" +#include "emel/memory/hybrid/errors.hpp" +#include "emel/model/loader/errors.hpp" +#include "emel/model/moshi/detail.hpp" +#include "emel/speech/generator/moshi/context.hpp" +#include "emel/speech/generator/moshi/detail.hpp" +#include "emel/speech/generator/moshi/events.hpp" + +namespace emel::speech::generator::moshi::guard { + +struct guard_bind_contract_valid { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + const auto &model = runtime_ev.request.model; + const auto &lm = model.moshi_lm; + int32_t max_delay = 0; + for (uint32_t index = 0; index < lm.delay_count; ++index) { + if (lm.delays[index] > max_delay) { + max_delay = lm.delays[index]; + } + } + const int32_t codebook_count = lm.n_q + 1; + const bool personaplex = lm.depformer_weights_per_step; + const int32_t delayed_dep_q = personaplex ? lm.inference_dep_q : lm.dep_q; + const int32_t needed_tokens = codebook_count - delayed_dep_q - 1; + const int32_t row_count = max_delay + 2 + static_cast(personaplex); + const bool inference_contract = + !personaplex || + (lm.inference_dep_q > 0 && lm.inference_dep_q <= lm.dep_q && + lm.inference_prompt_token_count == + static_cast(codebook_count) && + lm.inference_pre_text_silence_frames >= 0 && + lm.inference_post_text_silence_frames >= 0); + return emel::model::moshi::detail::validate_execution_contract(model) == + emel::error::cast(emel::model::loader::error::none) && + codebook_count > 0 && codebook_count <= action::k_max_codebooks && + lm.dep_q > 0 && lm.dep_q < codebook_count && delayed_dep_q > 0 && + delayed_dep_q <= lm.dep_q && needed_tokens >= 0 && row_count > 0 && + row_count <= action::k_max_delay_rows && inference_contract && + lm.delay_count >= static_cast(codebook_count); + } +}; + +struct guard_bind_contract_invalid { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_bind_contract_valid{}(runtime_ev, ctx); + } +}; + +struct guard_personaplex_lmgen { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.model.moshi_lm.depformer_weights_per_step; + } +}; + +struct guard_standard_lmgen { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_personaplex_lmgen{}(runtime_ev, ctx); + } +}; + +struct guard_voice_contract_valid { + bool operator()(const event::load_voice_run &runtime_ev, + const action::context &ctx) const noexcept { + emel::model::moshi::detail::execution_contract contract = {}; + const auto &voice_model = runtime_ev.request.voice_model; + const auto result = emel::model::moshi::detail::build_execution_contract( + voice_model, contract); + const auto *embeddings = contract.voice.embeddings.tensor; + const auto *cache = contract.voice.cache.tensor; + const auto embedding_type = + embeddings != nullptr ? static_cast(embeddings->type) : 0u; + const auto cache_type = + cache != nullptr ? static_cast(cache->type) : 0u; + const bool embedding_type_ok = + embedding_type == emel::kernel::detail::dtype_f32 || + embedding_type == emel::kernel::detail::dtype_f16 || + embedding_type == emel::kernel::detail::dtype_bf16; + return ctx.session.model != nullptr && + ctx.session.model->moshi_lm.depformer_weights_per_step && + ctx.lmgen.delayed_dep_q > 0 && + ctx.lmgen.delayed_dep_q == + ctx.session.model->moshi_lm.inference_dep_q && + result == emel::error::cast(emel::model::loader::error::none) && + contract.component == emel::model::data::moshi_component::voice && + embeddings != nullptr && cache != nullptr && + embeddings->n_dims == 4 && + embeddings->dims[0] == ctx.session.model->moshi_lm.dim && + embeddings->dims[1] == 1 && embeddings->dims[2] == 1 && + embeddings->dims[3] > 0 && + embeddings->dims[3] <= + static_cast(event::k_max_voice_embedding_dim) && + embedding_type_ok && cache->n_dims == 2 && + cache->dims[0] == ctx.lmgen.cache_row_count && + cache->dims[1] == ctx.lmgen.codebook_count && + cache_type == emel::kernel::detail::dtype_i32; + } +}; + +struct guard_voice_contract_invalid { + bool operator()(const event::load_voice_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_voice_contract_valid{}(runtime_ev, ctx); + } +}; + +struct guard_memory_accepted { + template + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + return ev.ctx.memory_accepted && + ev.ctx.memory_error == static_cast(emel::error::cast( + emel::memory::hybrid::error::none)); + } +}; + +struct guard_memory_rejected { + template + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_memory_accepted{}(runtime_ev, ctx); + } +}; + +struct guard_step_request_valid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + const bool input_full = runtime_ev.request.audio_tokens.size() == + static_cast(ctx.lmgen.codebook_count); + const bool input_tail = ctx.lmgen.needed_tokens > 0 && + runtime_ev.request.audio_tokens.size() >= + static_cast(ctx.lmgen.needed_tokens) && + runtime_ev.request.audio_tokens.size() != + static_cast(ctx.lmgen.codebook_count); + const bool input_optional = ctx.lmgen.needed_tokens == 0; + const bool voice_ready = + !ctx.voice.loaded || (ctx.voice.ready && ctx.voice.prompt_ready); + return ctx.session.model != nullptr && voice_ready && + runtime_ev.request.audio_tokens_out.data() != nullptr && + runtime_ev.request.audio_tokens_out.size() >= + static_cast(ctx.lmgen.delayed_dep_q) && + (input_full || input_tail || input_optional); + } +}; + +struct guard_step_request_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_step_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_step_blocked_by_voice_prompt { + bool operator()(const event::step_run &, + const action::context &ctx) const noexcept { + return ctx.session.model != nullptr && ctx.voice.loaded && + (!ctx.voice.ready || !ctx.voice.prompt_ready); + } +}; + +struct guard_step_request_shape_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_step_request_valid{}(runtime_ev, ctx) && + !guard_step_blocked_by_voice_prompt{}(runtime_ev, ctx); + } +}; + +struct guard_voice_prefill_request_valid { + bool operator()(const event::prefill_voice_run &, + const action::context &ctx) const noexcept { + return ctx.session.model != nullptr && ctx.voice.loaded && + !ctx.voice.ready && ctx.voice.prompt_frame_index >= 0 && + ctx.voice.prompt_frame_index < ctx.voice.prompt_frame_count && + ctx.voice.embedding_dim > 0 && + ctx.voice.embedding_dim <= + static_cast(event::k_max_voice_embedding_dim); + } +}; + +struct guard_voice_prefill_request_invalid { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_voice_prefill_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_voice_embedding_frame_f32 { + bool operator()(const event::prefill_voice_run &, + const action::context &ctx) const noexcept { + return ctx.voice.contract.voice.embeddings.tensor != nullptr && + static_cast( + ctx.voice.contract.voice.embeddings.tensor->type) == + emel::kernel::detail::dtype_f32; + } +}; + +struct guard_voice_embedding_frame_f16 { + bool operator()(const event::prefill_voice_run &, + const action::context &ctx) const noexcept { + return ctx.voice.contract.voice.embeddings.tensor != nullptr && + static_cast( + ctx.voice.contract.voice.embeddings.tensor->type) == + emel::kernel::detail::dtype_f16; + } +}; + +struct guard_voice_embedding_frame_bf16 { + bool operator()(const event::prefill_voice_run &, + const action::context &ctx) const noexcept { + return ctx.voice.contract.voice.embeddings.tensor != nullptr && + static_cast( + ctx.voice.contract.voice.embeddings.tensor->type) == + emel::kernel::detail::dtype_bf16; + } +}; + +struct guard_voice_embedding_frame_loaded { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.embedding_frame_ok; + } +}; + +struct guard_voice_embedding_frame_failed { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_voice_embedding_frame_loaded{}(runtime_ev, ctx); + } +}; + +struct guard_voice_prefill_complete { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.complete; + } +}; + +struct guard_voice_prefill_pending { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_voice_prefill_complete{}(runtime_ev, ctx); + } +}; + +struct guard_personaplex_prompt_begin_valid { + bool operator()(const event::begin_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + const int32_t frame_count = runtime_ev.request.pre_text_silence_frames + + runtime_ev.request.text_token_count + + runtime_ev.request.post_text_silence_frames; + return ctx.session.model != nullptr && ctx.voice.loaded && + ctx.voice.ready && !ctx.voice.prompt_ready && + !ctx.voice.prompt_started && + runtime_ev.request.text_token_count >= 0 && + runtime_ev.request.pre_text_silence_frames >= 0 && + runtime_ev.request.post_text_silence_frames >= 0 && + frame_count >= 0 && frame_count <= action::k_max_delay_rows && + ctx.session.model->moshi_lm.inference_prompt_token_count == + static_cast(ctx.lmgen.codebook_count); + } +}; + +struct guard_personaplex_prompt_begin_nonempty_valid { + bool operator()(const event::begin_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + const int32_t frame_count = runtime_ev.request.pre_text_silence_frames + + runtime_ev.request.text_token_count + + runtime_ev.request.post_text_silence_frames; + return guard_personaplex_prompt_begin_valid{}(runtime_ev, ctx) && + frame_count > 0; + } +}; + +struct guard_personaplex_prompt_begin_empty_valid { + bool operator()(const event::begin_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + const int32_t frame_count = runtime_ev.request.pre_text_silence_frames + + runtime_ev.request.text_token_count + + runtime_ev.request.post_text_silence_frames; + const auto *model = ctx.session.model; + const int32_t default_frame_count = + model == nullptr + ? -1 + : model->moshi_lm.inference_pre_text_silence_frames + + model->moshi_lm.inference_post_text_silence_frames; + return guard_personaplex_prompt_begin_valid{}(runtime_ev, ctx) && + frame_count == 0 && default_frame_count > 0 && + default_frame_count <= action::k_max_delay_rows; + } +}; + +struct guard_personaplex_prompt_begin_invalid { + bool operator()(const event::begin_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_personaplex_prompt_begin_nonempty_valid{}(runtime_ev, ctx) && + !guard_personaplex_prompt_begin_empty_valid{}(runtime_ev, ctx); + } +}; + +struct guard_personaplex_prompt_prefill_request_valid { + bool operator()(const event::prefill_personaplex_prompt_run &, + const action::context &ctx) const noexcept { + const int32_t frame_count = ctx.voice.pre_text_silence_remaining + + ctx.voice.text_tokens_remaining + + ctx.voice.post_text_silence_remaining; + return ctx.session.model != nullptr && ctx.voice.loaded && + ctx.voice.ready && ctx.voice.prompt_started && + !ctx.voice.prompt_ready && frame_count > 0; + } +}; + +struct guard_personaplex_prompt_prefill_request_invalid { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_personaplex_prompt_prefill_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_personaplex_prompt_pre_silence_pending { + bool operator()(const event::prefill_personaplex_prompt_run &, + const action::context &ctx) const noexcept { + return ctx.voice.pre_text_silence_remaining > 0; + } +}; + +struct guard_personaplex_prompt_text_pending { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return ctx.voice.pre_text_silence_remaining == 0 && + ctx.voice.text_tokens_remaining > 0 && + runtime_ev.request.text_token >= 0 && + runtime_ev.request.text_token < ctx.session.text_card; + } +}; + +struct guard_personaplex_prompt_post_silence_pending { + bool operator()(const event::prefill_personaplex_prompt_run &, + const action::context &ctx) const noexcept { + return ctx.voice.pre_text_silence_remaining == 0 && + ctx.voice.text_tokens_remaining == 0 && + ctx.voice.post_text_silence_remaining > 0; + } +}; + +struct guard_personaplex_prompt_phase_invalid { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_personaplex_prompt_pre_silence_pending{}(runtime_ev, ctx) && + !guard_personaplex_prompt_text_pending{}(runtime_ev, ctx) && + !guard_personaplex_prompt_post_silence_pending{}(runtime_ev, ctx); + } +}; + +struct guard_personaplex_prompt_complete { + bool operator()(const event::prefill_personaplex_prompt_run &, + const action::context &ctx) const noexcept { + return ctx.voice.pre_text_silence_remaining == 0 && + ctx.voice.text_tokens_remaining == 0 && + ctx.voice.post_text_silence_remaining == 0; + } +}; + +struct guard_personaplex_prompt_pending { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_personaplex_prompt_complete{}(runtime_ev, ctx); + } +}; + +struct guard_has_personaplex_prompt_complete_out { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.complete_out != nullptr; + } +}; + +struct guard_no_personaplex_prompt_complete_out { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_personaplex_prompt_complete_out{}(runtime_ev, ctx); + } +}; + +struct guard_has_personaplex_prompt_remaining_out { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.remaining_frames_out != nullptr; + } +}; + +struct guard_no_personaplex_prompt_remaining_out { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_personaplex_prompt_remaining_out{}(runtime_ev, ctx); + } +}; + +struct guard_has_voice_complete_out { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.complete_out != nullptr; + } +}; + +struct guard_no_voice_complete_out { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_voice_complete_out{}(runtime_ev, ctx); + } +}; + +struct guard_has_voice_remaining_out { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.remaining_frames_out != nullptr; + } +}; + +struct guard_no_voice_remaining_out { + bool operator()(const event::prefill_voice_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_voice_remaining_out{}(runtime_ev, ctx); + } +}; + +struct guard_has_full_input { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.request.audio_tokens.size() == + static_cast(ctx.lmgen.codebook_count); + } +}; + +struct guard_has_tail_input { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return ctx.lmgen.needed_tokens > 0 && + runtime_ev.request.audio_tokens.size() >= + static_cast(ctx.lmgen.needed_tokens) && + runtime_ev.request.audio_tokens.size() != + static_cast(ctx.lmgen.codebook_count); + } +}; + +struct guard_has_no_input_write { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_full_input{}(runtime_ev, ctx) && + !guard_has_tail_input{}(runtime_ev, ctx); + } +}; + +struct guard_graph_runtime_available { + template + bool operator()(const runtime_event_type &, + const action::context &ctx) const noexcept { + return ctx.graph.executor != nullptr && ctx.graph.dispatch_step != nullptr; + } +}; + +struct guard_graph_runtime_unavailable { + template + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_graph_runtime_available{}(runtime_ev, ctx); + } +}; + +struct guard_graph_step_accepted { + template + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + return ev.ctx.graph_accepted && + ev.ctx.graph_error == action::detail_ns::to_error(error::none); + } +}; + +struct guard_graph_step_rejected { + template + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_graph_step_accepted{}(runtime_ev, ctx); + } +}; + +struct guard_graph_step_accepted_personaplex_prompt_pre_silence { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_graph_step_accepted{}(runtime_ev, ctx) && + guard_personaplex_prompt_pre_silence_pending{}(runtime_ev, ctx); + } +}; + +struct guard_graph_step_accepted_personaplex_prompt_text { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_graph_step_accepted{}(runtime_ev, ctx) && + guard_personaplex_prompt_text_pending{}(runtime_ev, ctx); + } +}; + +struct guard_graph_step_accepted_personaplex_prompt_post_silence { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_graph_step_accepted{}(runtime_ev, ctx) && + guard_personaplex_prompt_post_silence_pending{}(runtime_ev, ctx); + } +}; + +struct guard_has_graph_error_out { + template + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + return ev.request.graph_error_out != nullptr; + } +}; + +struct guard_no_graph_error_out { + template + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_graph_error_out{}(runtime_ev, ctx); + } +}; + +struct guard_replace_depformer_tokens { + bool operator()(const event::step_run &, + const action::context &ctx) const noexcept { + return ctx.lmgen.delay_steps > 0 && + ctx.lmgen.offset < ctx.lmgen.delay_steps; + } +}; + +struct guard_use_graph_audio_tokens { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_replace_depformer_tokens{}(runtime_ev, ctx); + } +}; + +struct guard_should_write_generated { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.ctx.provided_input; + } +}; + +struct guard_provided_input { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.provided_input; + } +}; + +struct guard_skip_pending { + bool operator()(const event::step_run &, + const action::context &ctx) const noexcept { + return ctx.lmgen.skip > 0; + } +}; + +struct guard_before_delay { + bool operator()(const event::step_run &, + const action::context &ctx) const noexcept { + return ctx.lmgen.offset <= ctx.lmgen.max_delay; + } +}; + +struct guard_past_delay { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_skip_pending{}(runtime_ev, ctx) && + !guard_before_delay{}(runtime_ev, ctx); + } +}; + +struct guard_output_has_ungenerated { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + bool has_ungenerated = false; + for (int32_t index = 0; index < runtime_ev.ctx.delayed_dep_q; ++index) { + if (runtime_ev.request.audio_tokens_out[static_cast(index)] == + action::k_token_zero) { + has_ungenerated = true; + } + } + return has_ungenerated; + } +}; + +struct guard_output_complete { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_output_has_ungenerated{}(runtime_ev, ctx); + } +}; + +struct guard_has_produced_out { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.produced_out != nullptr; + } +}; + +struct guard_no_produced_out { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_produced_out{}(runtime_ev, ctx); + } +}; + +template struct guard_has_error_out { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.error_out != nullptr; + } +}; + +template struct guard_no_error_out { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_error_out{}(runtime_ev, ctx); + } +}; + +template struct guard_has_done_callback { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return static_cast(runtime_ev.request.on_done); + } +}; + +template struct guard_no_done_callback { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_done_callback{}(runtime_ev, ctx); + } +}; + +template struct guard_has_error_callback { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return static_cast(runtime_ev.request.on_error); + } +}; + +template struct guard_no_error_callback { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_has_error_callback{}(runtime_ev, ctx); + } +}; + +struct guard_unexpected_error_out_present { + template + bool operator()(const event_type &ev, + const action::context &) const noexcept { + if constexpr (requires { + ev.ctx.err; + ev.request.error_out; + }) { + return ev.request.error_out != nullptr; + } else { + return false; + } + } +}; + +struct guard_unexpected_error_out_absent { + template + bool operator()(const event_type &ev, + const action::context &ctx) const noexcept { + return !guard_unexpected_error_out_present{}(ev, ctx); + } +}; + +} // namespace emel::speech::generator::moshi::guard diff --git a/src/emel/speech/generator/moshi/sm.hpp b/src/emel/speech/generator/moshi/sm.hpp new file mode 100644 index 00000000..78639a67 --- /dev/null +++ b/src/emel/speech/generator/moshi/sm.hpp @@ -0,0 +1,741 @@ +#pragma once + +#include + +#include + +#include "emel/sm.hpp" +#include "emel/speech/generator/moshi/actions.hpp" +#include "emel/speech/generator/moshi/context.hpp" +#include "emel/speech/generator/moshi/events.hpp" +#include "emel/speech/generator/moshi/guards.hpp" + +namespace emel::speech::generator::moshi { + +struct state_uninitialized {}; +struct state_bind_contract_decision {}; +struct state_binding {}; +struct state_lmgen_mode_decision {}; +struct state_configure_lmgen {}; +struct state_reserve_memory {}; +struct state_reserve_memory_decision {}; +struct state_allocate_sequence {}; +struct state_allocate_sequence_decision {}; +struct state_init_error_out_decision {}; +struct state_init_callback_decision {}; +struct state_init_failed_error_out_decision {}; +struct state_init_failed_callback_decision {}; +struct state_session_ready {}; +struct state_voice_request_decision {}; +struct state_voice_error_out_decision {}; +struct state_voice_callback_decision {}; +struct state_voice_failed_error_out_decision {}; +struct state_voice_failed_callback_decision {}; +struct state_prefill_voice_request_decision {}; +struct state_prefill_voice_allocate_slot {}; +struct state_prefill_voice_allocate_slot_decision {}; +struct state_prefill_voice_capture_memory {}; +struct state_prefill_voice_capture_memory_decision {}; +struct state_prefill_voice_begin {}; +struct state_prefill_voice_embedding_frame {}; +struct state_prefill_voice_embedding_frame_decision {}; +struct state_prefill_voice_graph_runtime_decision {}; +struct state_prefill_voice_running_graph {}; +struct state_prefill_voice_graph_error_out_decision {}; +struct state_prefill_voice_graph_result_decision {}; +struct state_prefill_voice_advance {}; +struct state_prefill_voice_complete_decision {}; +struct state_prefill_voice_output_decision {}; +struct state_prefill_voice_remaining_out_decision {}; +struct state_prefill_voice_error_out_decision {}; +struct state_prefill_voice_callback_decision {}; +struct state_prefill_voice_failed_error_out_decision {}; +struct state_prefill_voice_failed_callback_decision {}; +struct state_personaplex_prompt_begin_decision {}; +struct state_personaplex_prompt_begin_error_out_decision {}; +struct state_personaplex_prompt_begin_callback_decision {}; +struct state_personaplex_prompt_begin_failed_error_out_decision {}; +struct state_personaplex_prompt_begin_failed_callback_decision {}; +struct state_prefill_personaplex_prompt_request_decision {}; +struct state_prefill_personaplex_prompt_allocate_slot {}; +struct state_prefill_personaplex_prompt_allocate_slot_decision {}; +struct state_prefill_personaplex_prompt_capture_memory {}; +struct state_prefill_personaplex_prompt_capture_memory_decision {}; +struct state_prefill_personaplex_prompt_begin {}; +struct state_prefill_personaplex_prompt_phase_decision {}; +struct state_prefill_personaplex_prompt_frame {}; +struct state_prefill_personaplex_prompt_write_input {}; +struct state_prefill_personaplex_prompt_graph_runtime_decision {}; +struct state_prefill_personaplex_prompt_running_graph {}; +struct state_prefill_personaplex_prompt_graph_error_out_decision {}; +struct state_prefill_personaplex_prompt_graph_result_decision {}; +struct state_prefill_personaplex_prompt_advance {}; +struct state_prefill_personaplex_prompt_complete_decision {}; +struct state_prefill_personaplex_prompt_output_decision {}; +struct state_prefill_personaplex_prompt_remaining_out_decision {}; +struct state_prefill_personaplex_prompt_error_out_decision {}; +struct state_prefill_personaplex_prompt_callback_decision {}; +struct state_prefill_personaplex_prompt_failed_error_out_decision {}; +struct state_prefill_personaplex_prompt_failed_callback_decision {}; +struct state_step_request_decision {}; +struct state_allocate_step_slot {}; +struct state_allocate_step_slot_decision {}; +struct state_capture_memory {}; +struct state_capture_memory_decision {}; +struct state_step_begin {}; +struct state_input_write_decision {}; +struct state_build_input_sequence {}; +struct state_graph_runtime_decision {}; +struct state_running_graph {}; +struct state_graph_error_out_decision {}; +struct state_graph_result_decision {}; +struct state_depformer_decision {}; +struct state_apply_delay_mask {}; +struct state_write_generated_decision {}; +struct state_skip_delay_decision {}; +struct state_collect_output {}; +struct state_output_decision {}; +struct state_step_produced_out_decision {}; +struct state_step_error_out_decision {}; +struct state_step_callback_decision {}; +struct state_step_failed_error_out_decision {}; +struct state_step_failed_callback_decision {}; +struct state_uninit_step_error_out_decision {}; +struct state_uninit_step_callback_decision {}; +struct state_uninit_voice_error_out_decision {}; +struct state_uninit_voice_callback_decision {}; +struct state_uninit_prefill_voice_error_out_decision {}; +struct state_uninit_prefill_voice_callback_decision {}; +struct state_uninit_begin_personaplex_prompt_error_out_decision {}; +struct state_uninit_begin_personaplex_prompt_callback_decision {}; +struct state_uninit_prefill_personaplex_prompt_error_out_decision {}; +struct state_uninit_prefill_personaplex_prompt_callback_decision {}; + +struct model { + auto operator()() const { + namespace sml = stateforward::sml; + using init_run = event::initialize_run; + using begin_prompt_run = event::begin_personaplex_prompt_run; + using load_voice_run = event::load_voice_run; + using prefill_prompt_run = event::prefill_personaplex_prompt_run; + using prefill_voice_run = event::prefill_voice_run; + using step_run = event::step_run; + + // clang-format off + return sml::make_transition_table( + //------------------------------------------------------------------------------// + // Initialization: Moshi contract, then Cortext-owned memory reservation. + sml::state <= *sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_bind_contract_valid{} ] + / action::effect_bind_contract{} + , sml::state <= sml::state + + sml::completion [ guard::guard_bind_contract_invalid{} ] + / action::effect_mark_bind_failed{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_lmgen{} ] + / action::effect_configure_personaplex_lmgen{} + , sml::state <= sml::state + + sml::completion [ guard::guard_standard_lmgen{} ] + / action::effect_configure_standard_lmgen{} + , sml::state <= sml::state + + sml::completion + / action::effect_reserve_memory{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + / action::effect_allocate_sequence{} + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_done_callback{} ] + / action::effect_emit_initialize_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_done_callback{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_initialize_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + //------------------------------------------------------------------------------// + // PersonaPlex voice prompt: bind NATF0/voice GGUF first, then consume + // one prompt embedding frame per top-level RTC prefill dispatch. + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_contract_valid{} ] + / action::effect_bind_voice_contract{} + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_contract_invalid{} ] + / action::effect_mark_voice_contract_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_done_callback{} ] + / action::effect_emit_load_voice_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_done_callback{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_load_voice_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_prefill_request_valid{} ] + / action::effect_allocate_voice_prefill_slot{} + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_prefill_request_invalid{} ] + / action::effect_mark_voice_contract_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + / action::effect_capture_voice_prefill_memory{} + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + / action::effect_begin_voice_prefill{} + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_embedding_frame_f32{} ] + / action::effect_load_voice_embedding_frame_f32{} + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_embedding_frame_f16{} ] + / action::effect_load_voice_embedding_frame_f16{} + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_embedding_frame_bf16{} ] + / action::effect_load_voice_embedding_frame_bf16{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_embedding_frame_loaded{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_embedding_frame_failed{} ] + / action::effect_mark_voice_contract_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_runtime_available{} ] + / action::effect_run_voice_graph_runtime{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_runtime_unavailable{} ] + / action::effect_mark_graph_runtime_unavailable{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_has_graph_error_out{} ] + / action::effect_store_graph_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_graph_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_accepted{} ] + / action::effect_advance_voice_prefill{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_rejected{} ] + / action::effect_mark_graph_runtime_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_prefill_complete{} ] + / action::effect_copy_voice_cache{} + , sml::state <= sml::state + + sml::completion [ guard::guard_voice_prefill_pending{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_voice_complete_out{} ] + / action::effect_store_voice_complete_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_voice_complete_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_voice_remaining_out{} ] + / action::effect_store_voice_remaining_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_voice_remaining_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_done_callback{} ] + / action::effect_emit_prefill_voice_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_done_callback{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_prefill_voice_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + //------------------------------------------------------------------------------// + // PersonaPlex system prompt: after voice embeddings/cache are loaded, consume + // the reference silence/text/silence prompt frames one RTC dispatch at a time. + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_begin_nonempty_valid{} ] + / action::effect_bind_personaplex_prompt{} + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_begin_empty_valid{} ] + / action::effect_bind_empty_personaplex_prompt{} + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_begin_invalid{} ] + / action::effect_mark_personaplex_prompt_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_done_callback{} ] + / action::effect_emit_begin_personaplex_prompt_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_done_callback{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_begin_personaplex_prompt_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_prefill_request_valid{} ] + / action::effect_allocate_personaplex_prompt_slot{} + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_prefill_request_invalid{} ] + / action::effect_mark_personaplex_prompt_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + / action::effect_capture_personaplex_prompt_memory{} + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + / action::effect_begin_personaplex_prompt_prefill{} + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_pre_silence_pending{} ] + / action::effect_build_personaplex_prompt_silence_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_text_pending{} ] + / action::effect_build_personaplex_prompt_text_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_post_silence_pending{} ] + / action::effect_build_personaplex_prompt_silence_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_phase_invalid{} ] + / action::effect_mark_personaplex_prompt_error{} + , sml::state <= sml::state + + sml::completion + / action::effect_write_and_build_personaplex_prompt_input{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_runtime_available{} ] + / action::effect_run_personaplex_prompt_graph_runtime{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_runtime_unavailable{} ] + / action::effect_mark_graph_runtime_unavailable{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_has_graph_error_out{} ] + / action::effect_store_graph_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_graph_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_accepted_personaplex_prompt_pre_silence{} ] + / action::effect_advance_personaplex_prompt_pre_silence{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_accepted_personaplex_prompt_text{} ] + / action::effect_advance_personaplex_prompt_text{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_accepted_personaplex_prompt_post_silence{} ] + / action::effect_advance_personaplex_prompt_post_silence{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_rejected{} ] + / action::effect_mark_graph_runtime_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_complete{} ] + / action::effect_finish_personaplex_prompt{} + , sml::state <= sml::state + + sml::completion [ guard::guard_personaplex_prompt_pending{} ] + / action::effect_publish_personaplex_prompt_pending{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_personaplex_prompt_complete_out{} ] + / action::effect_store_personaplex_prompt_complete_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_personaplex_prompt_complete_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_personaplex_prompt_remaining_out{} ] + / action::effect_store_personaplex_prompt_remaining_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_personaplex_prompt_remaining_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_done_callback{} ] + / action::effect_emit_prefill_personaplex_prompt_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_done_callback{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_prefill_personaplex_prompt_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + //------------------------------------------------------------------------------// + // Online step: validate audio-token frame, allocate the next + // Cortext-owned KV slot, capture memory, then enter the explicitly + // modeled Moshi graph execution route. + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_step_request_valid{} ] + / action::effect_allocate_step_slot{} + , sml::state <= sml::state + + sml::completion [ guard::guard_step_blocked_by_voice_prompt{} ] + / action::effect_mark_voice_prompt_pending{} + , sml::state <= sml::state + + sml::completion [ guard::guard_step_request_shape_invalid{} ] + / action::effect_mark_step_request_invalid{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + / action::effect_capture_memory{} + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_accepted{} ] + / action::effect_begin_step{} + , sml::state <= sml::state + + sml::completion [ guard::guard_memory_rejected{} ] + / action::effect_mark_memory_error{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_has_full_input{} ] + / action::effect_write_full_input{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_tail_input{} ] + / action::effect_write_tail_input{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_no_input_write{} ] + , sml::state <= sml::state + + sml::completion + / action::effect_build_input_sequence{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_runtime_available{} ] + / action::effect_run_graph_runtime{} + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_runtime_unavailable{} ] + / action::effect_mark_graph_runtime_unavailable{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_has_graph_error_out{} ] + / action::effect_store_graph_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_graph_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_accepted{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_step_rejected{} ] + / action::effect_mark_graph_runtime_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_replace_depformer_tokens{} ] + / action::effect_replace_audio_with_zero{} + , sml::state <= sml::state + + sml::completion [ guard::guard_use_graph_audio_tokens{} ] + , sml::state <= sml::state + + sml::completion + / action::effect_apply_delay_mask_and_advance{} + , sml::state <= sml::state + + sml::completion [ guard::guard_should_write_generated{} ] + / action::effect_write_generated{} + , sml::state <= sml::state + + sml::completion [ guard::guard_provided_input{} ] + / action::effect_write_generated_missing{} + , sml::state <= sml::state + + sml::completion [ guard::guard_skip_pending{} ] + / action::effect_consume_skip{} + , sml::state <= sml::state + + sml::completion [ guard::guard_before_delay{} ] + / action::effect_publish_no_output{} + , sml::state <= sml::state + + sml::completion [ guard::guard_past_delay{} ] + / action::effect_collect_delayed_output{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_output_has_ungenerated{} ] + / action::effect_publish_no_output{} + , sml::state <= sml::state + + sml::completion [ guard::guard_output_complete{} ] + / action::effect_publish_output{} + + , sml::state <= sml::state + + sml::completion [ guard::guard_has_produced_out{} ] + / action::effect_store_produced_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_produced_out{} ] + + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_done_callback{} ] + / action::effect_emit_step_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_done_callback{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_step_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + //------------------------------------------------------------------------------// + // Requests before initialization answer with explicit errors. + , sml::state <= sml::state + + sml::event + / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_step_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + , sml::state <= sml::state + + sml::event + / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_load_voice_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + , sml::state <= sml::state + + sml::event + / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_prefill_voice_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + , sml::state <= sml::state + + sml::event + / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_begin_personaplex_prompt_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + , sml::state <= sml::state + + sml::event + / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_callback{} ] + / action::effect_emit_prefill_personaplex_prompt_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_callback{} ] + + //------------------------------------------------------------------------------// + // Reset. + , sml::state <= sml::state + + sml::event + / action::effect_reset_session{} + + //------------------------------------------------------------------------------// + // Unexpected events. + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_present{} ] + / action::effect_mark_unexpected_and_store{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_absent{} ] + / action::effect_mark_unexpected{} + ); + // clang-format on + } +}; + +struct sm : public emel::sm { + using base_type = emel::sm; + using base_type::is; + using base_type::visit_current_states; + + sm() : memory_snapshot_(std::make_unique()) {} + explicit sm(const emel::memory::hybrid::kv_binding &kv_cache) + : base_type(std::in_place, kv_cache), + memory_snapshot_(std::make_unique()) {} + sm(const emel::memory::hybrid::kv_binding &kv_cache, + const action::graph_binding &graph_executor) + : base_type(std::in_place, kv_cache, graph_executor), + memory_snapshot_(std::make_unique()) {} + + sm(const sm &) = delete; + sm &operator=(const sm &) = delete; + sm(sm &&) = delete; + sm &operator=(sm &&) = delete; + + bool process_event(const event::initialize &ev) { + event::initialize_ctx ctx{}; + event::initialize_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::load_voice &ev) { + event::load_voice_ctx ctx{}; + event::load_voice_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::begin_personaplex_prompt &ev) { + event::begin_personaplex_prompt_ctx ctx{}; + event::begin_personaplex_prompt_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::prefill_voice &ev) { + event::prefill_voice_ctx ctx{*memory_snapshot_}; + event::prefill_voice_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::prefill_personaplex_prompt &ev) { + event::prefill_personaplex_prompt_ctx ctx{*memory_snapshot_}; + event::prefill_personaplex_prompt_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::step &ev) { + event::step_ctx ctx{*memory_snapshot_}; + event::step_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::reset &ev) { + event::reset_run runtime_ev{ev}; + return base_type::process_event(runtime_ev); + } + +private: + std::unique_ptr memory_snapshot_ = {}; +}; + +using Generator = sm; + +} // namespace emel::speech::generator::moshi diff --git a/tests/kernel/aarch64_tests.cpp b/tests/kernel/aarch64_tests.cpp index b0347ad8..ced9491f 100644 --- a/tests/kernel/aarch64_tests.cpp +++ b/tests/kernel/aarch64_tests.cpp @@ -55,7 +55,9 @@ std::filesystem::path repo_root() { #ifdef EMEL_TEST_REPO_ROOT return std::filesystem::path{EMEL_TEST_REPO_ROOT}; #else - return std::filesystem::path{__FILE__}.parent_path().parent_path() + return std::filesystem::path{__FILE__} + .parent_path() + .parent_path() .parent_path(); #endif } @@ -69,15 +71,14 @@ std::string read_text_file(const std::filesystem::path &path) { // Mirrors the generator's parallel matmul lane slicing: a group-aligned row // slice of src0/dst embedded in the full batch-major output, sharing src1. -inline emel::kernel::event::op_mul_mat make_row_sliced_lane_event( - const emel::kernel::event::op_mul_mat & ev, - const uint64_t group_rows, - const uint64_t row_begin, - const uint64_t row_count) { +inline emel::kernel::event::op_mul_mat +make_row_sliced_lane_event(const emel::kernel::event::op_mul_mat &ev, + const uint64_t group_rows, const uint64_t row_begin, + const uint64_t row_count) { emel::kernel::event::op_mul_mat sliced = ev; const uint64_t slice_groups = (row_count + group_rows - 1u) / group_rows; sliced.src0.data = static_cast(ev.src0.data) + - (row_begin / group_rows) * ev.src0.nb[1]; + (row_begin / group_rows) * ev.src0.nb[1]; sliced.src0.ne[1] = row_count; sliced.src0.nb[2] = ev.src0.nb[1] * slice_groups; sliced.src0.nb[3] = sliced.src0.nb[2]; @@ -89,7 +90,7 @@ inline emel::kernel::event::op_mul_mat make_row_sliced_lane_event( return sliced; } -} // namespace +} // namespace TEST_CASE("kernel_aarch64_numeric_paths") { float lhs[4] = {1.0f, 2.0f, 3.0f, 4.0f}; @@ -1897,7 +1898,8 @@ TEST_CASE("kernel_aarch64_f16_mul_mat_without_neon_takes_shared_route") { } } -TEST_CASE("kernel_aarch64_f32_vector_gemv_route_is_explicit_and_bit_identical") { +TEST_CASE( + "kernel_aarch64_f32_vector_gemv_route_is_explicit_and_bit_identical") { // k covers four 16-wide f32 steps plus a 6-element scalar tail so the // vfmaq body and the leftover loop of the ported ggml_vec_dot_f32 both // execute. Integer-valued inputs keep every product and partial sum @@ -2172,14 +2174,28 @@ TEST_CASE("kernel_aarch64_q4_k_uses_neon_dispatch_when_dotprod_is_available") { #if defined(__ARM_FEATURE_DOTPROD) CHECK(emel::kernel::aarch64::detail::can_use_neon(shared_ev, true)); + CHECK(emel::kernel::aarch64::detail:: + can_use_neon_mul_mat_q4_vector_f32_rhs(shared_ev, true)); #else CHECK_FALSE(emel::kernel::aarch64::detail::can_use_neon(shared_ev, true)); + CHECK_FALSE(emel::kernel::aarch64::detail:: + can_use_neon_mul_mat_q4_vector_f32_rhs(shared_ev, true)); #endif aarch64_sm machine{}; CHECK(machine.process_event(shared_ev)); CHECK(shared_out[0] == doctest::Approx(scalar_out[0]).epsilon(1.0e-6f)); CHECK(shared_out[0] == doctest::Approx(-256.0f).epsilon(1.0e-6f)); +#if defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD) + CHECK(machine.optimized_q4_dispatch_count() == 1u); + CHECK(machine.optimized_q4_vector_dispatch_count() == 1u); + CHECK(machine.shared_q4_dispatch_count() == 0u); +#else + CHECK(machine.optimized_q4_dispatch_count() == 0u); + CHECK(machine.optimized_q4_vector_dispatch_count() == 0u); + CHECK(machine.shared_q4_dispatch_count() == 1u); +#endif } TEST_CASE("kernel_aarch64_supported_quantized_dispatch_is_alloc_free") { @@ -2546,6 +2562,7 @@ TEST_CASE( std::array native_out = {}; std::array packed_bl4_out = {}; std::array packed_bl8_out = {}; + std::array packed_bl8_f32_out = {}; const emel::kernel::event::op_mul_mat native_ev{ .src0 = make_quantized_src(native_rows.data(), dtype::q4_k, QK_K, Q4_K_X8_ROWS), @@ -2564,20 +2581,54 @@ TEST_CASE( .src1 = make_q8_k_vector_src(q8_input.data(), QK_K), .dst = make_dst(packed_bl8_out.data(), dtype::f32, 1u, Q4_K_X8_ROWS), }; + const emel::kernel::event::op_mul_mat packed_bl8_f32_ev{ + .src0 = make_packed_q4_k_x8_bl8_src(packed_bl8_storage.data(), QK_K, + Q4_K_X8_ROWS), + .src1 = make_src(input.data(), dtype::f32, 1u, QK_K), + .dst = + make_dst(packed_bl8_f32_out.data(), dtype::f32, 1u, Q4_K_X8_ROWS), + }; + float argmax_score = 0.0f; + int32_t argmax_index = -1; + const emel::kernel::event::op_mul_mat_argmax packed_bl8_f32_argmax_ev{ + .src0 = make_packed_q4_k_x8_bl8_src(packed_bl8_storage.data(), QK_K, + Q4_K_X8_ROWS), + .src1 = make_src(input.data(), dtype::f32, 1u, QK_K), + .dst = make_dst(&argmax_score, dtype::f32, 1u, 1u), + .index_out = &argmax_index, + }; aarch64_sm native_machine{}; aarch64_sm packed_bl4_machine{}; aarch64_sm packed_bl8_machine{}; + aarch64_sm packed_bl8_f32_machine{}; + aarch64_sm packed_bl8_f32_argmax_machine{}; CHECK(native_machine.process_event(native_ev)); CHECK(packed_bl4_machine.process_event(packed_bl4_ev)); CHECK(packed_bl8_machine.process_event(packed_bl8_ev)); + CHECK(packed_bl8_f32_machine.process_event(packed_bl8_f32_ev)); + CHECK(packed_bl8_f32_argmax_machine.process_event( + packed_bl8_f32_argmax_ev)); + + int32_t expected_argmax_index = 0; + float expected_argmax_score = native_out[0]; + for (size_t row = 1; row < native_out.size(); ++row) { + if (native_out[row] > expected_argmax_score) { + expected_argmax_score = native_out[row]; + expected_argmax_index = static_cast(row); + } + } for (size_t row = 0; row < native_out.size(); ++row) { CHECK(packed_bl4_out[row] == doctest::Approx(native_out[row]).epsilon(1.0e-5f)); CHECK(packed_bl8_out[row] == doctest::Approx(native_out[row]).epsilon(1.0e-5f)); + CHECK(packed_bl8_f32_out[row] == + doctest::Approx(native_out[row]).epsilon(1.0e-5f)); } + CHECK(argmax_index == expected_argmax_index); + CHECK(argmax_score == doctest::Approx(expected_argmax_score).epsilon(1.0e-5f)); CHECK(packed_bl4_machine.optimized_q4_dispatch_count() == 1u); CHECK(packed_bl4_machine.optimized_q4_vector_dispatch_count() == 1u); @@ -2591,11 +2642,24 @@ TEST_CASE( CHECK(packed_bl8_machine.optimized_q4_vector_packed_q8_rhs_dispatch_count() == 1u); CHECK(packed_bl8_machine.shared_q4_dispatch_count() == 0u); + CHECK(packed_bl8_f32_machine.optimized_q4_dispatch_count() == 1u); + CHECK(packed_bl8_f32_machine.optimized_q4_vector_dispatch_count() == 1u); + CHECK(packed_bl8_f32_machine.optimized_q4_vector_packed_dispatch_count() == + 1u); + CHECK(packed_bl8_f32_machine + .optimized_q4_vector_packed_q8_rhs_dispatch_count() == 0u); + CHECK(packed_bl8_f32_machine.shared_q4_dispatch_count() == 0u); + CHECK(packed_bl8_f32_argmax_machine.optimized_q4_dispatch_count() == 1u); + CHECK(packed_bl8_f32_argmax_machine.optimized_q4_vector_dispatch_count() == + 1u); + CHECK(packed_bl8_f32_argmax_machine + .optimized_q4_vector_packed_dispatch_count() == 1u); + CHECK(packed_bl8_f32_argmax_machine.shared_q4_dispatch_count() == 0u); #endif } -TEST_CASE( - "kernel_aarch64_raw_quantized_prepared_rhs_routes_are_explicit_and_numeric_match") { +TEST_CASE("kernel_aarch64_raw_quantized_prepared_rhs_routes_are_explicit_and_" + "numeric_match") { #if !(defined(__aarch64__) && defined(__ARM_NEON) && \ defined(__ARM_FEATURE_DOTPROD)) CHECK(true); @@ -3470,10 +3534,10 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_multi_block_matrix_x8_route_matches_" #endif } -TEST_CASE("kernel_aarch64_q4_k_packed_bl8_routes_do_not_compile_bad_i8mm_tile") { - const std::string actions_source = - read_text_file(repo_root() / "src" / "emel" / "kernel" / "aarch64" / - "actions.hpp"); +TEST_CASE( + "kernel_aarch64_q4_k_packed_bl8_routes_do_not_compile_bad_i8mm_tile") { + const std::string actions_source = read_text_file( + repo_root() / "src" / "emel" / "kernel" / "aarch64" / "actions.hpp"); CHECK(actions_source.find("dot_q4_k_x8_q8_k_group_bl8_i8mm_x4") == std::string::npos); } @@ -3896,11 +3960,12 @@ TEST_CASE("kernel_aarch64_q6_k_prepared_q8_rhs_i8mm_multi_block_matrix_x4_" #endif } -TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x8_row_sliced_lane_views_are_supported") { - using emel::kernel::detail::quant::Q4_K_X8_ROWS; - using emel::kernel::detail::quant::QK_K; +TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x8_row_sliced_lane_views_are_" + "supported") { using emel::kernel::detail::quant::block_q4_k; using emel::kernel::detail::quant::block_q8_k; + using emel::kernel::detail::quant::Q4_K_X8_ROWS; + using emel::kernel::detail::quant::QK_K; constexpr uint64_t row_count = 16u; constexpr uint64_t slice_rows = Q4_K_X8_ROWS; @@ -3908,13 +3973,15 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x8_row_sliced_lane_views_are_su constexpr uint64_t col_count = QK_K; constexpr uint64_t block_count = col_count / QK_K; - std::vector native_rows(static_cast(row_count * block_count)); + std::vector native_rows( + static_cast(row_count * block_count)); for (size_t row = 0; row < static_cast(row_count); ++row) { - auto & q4 = native_rows[row]; + auto &q4 = native_rows[row]; q4.d = 0x3c00u; q4.dmin = static_cast(0x3600u + row * 0x0020u); for (size_t idx = 0; idx < q4.scales.size(); ++idx) { - q4.scales[idx] = static_cast((idx * (13u + row)) ^ (0x66u - row)); + q4.scales[idx] = + static_cast((idx * (13u + row)) ^ (0x66u - row)); } for (size_t idx = 0; idx < q4.qs.size(); ++idx) { q4.qs[idx] = static_cast((idx * (7u + row)) ^ (0xa5u + row)); @@ -3934,15 +4001,15 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x8_row_sliced_lane_views_are_su std::vector rhs_q8(static_cast(rhs_rows * block_count)); for (size_t row = 0; row < static_cast(rhs_rows); ++row) { emel::kernel::detail::quant::quantize_row_q8_k_strided( - rhs_dense.data() + row * static_cast(col_count), - 1u, + rhs_dense.data() + row * static_cast(col_count), 1u, rhs_q8.data() + row * static_cast(block_count), static_cast(col_count)); } std::vector reference(static_cast(rhs_rows * row_count), 0.0f); for (size_t rhs_row = 0; rhs_row < static_cast(rhs_rows); ++rhs_row) { - for (size_t lhs_row = 0; lhs_row < static_cast(row_count); ++lhs_row) { + for (size_t lhs_row = 0; lhs_row < static_cast(row_count); + ++lhs_row) { reference[rhs_row * static_cast(row_count) + lhs_row] = emel::kernel::detail::dot_q4_k_q8_k_row_scalar( native_rows.data() + lhs_row * static_cast(block_count), @@ -3953,24 +4020,29 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x8_row_sliced_lane_views_are_su std::vector packed_bl8( sizeof(emel::kernel::detail::quant::block_q4_kx8) * - emel::kernel::detail::quant::packed_q4_k_x8_group_count(row_count) * block_count); + emel::kernel::detail::quant::packed_q4_k_x8_group_count(row_count) * + block_count); REQUIRE(emel::kernel::detail::quant::pack_q4_k_rows_x8_bl8( native_rows.data(), row_count, col_count, packed_bl8.data())); - std::vector packed_out(static_cast(rhs_rows * row_count), 0.0f); + std::vector packed_out(static_cast(rhs_rows * row_count), + 0.0f); aarch64_sm machine{}; const emel::kernel::event::op_mul_mat full_ev{ - .src0 = make_packed_q4_k_x8_bl8_src(packed_bl8.data(), col_count, row_count), + .src0 = + make_packed_q4_k_x8_bl8_src(packed_bl8.data(), col_count, row_count), .src1 = make_q8_k_x8_rhs_src(rhs_q8.data(), rhs_rows, col_count), - .dst = make_batch_major_dst(packed_out.data(), dtype::f32, rhs_rows, row_count), + .dst = make_batch_major_dst(packed_out.data(), dtype::f32, rhs_rows, + row_count), }; const auto lane0 = make_row_sliced_lane_event(full_ev, Q4_K_X8_ROWS, 0u, slice_rows); - const auto lane1 = - make_row_sliced_lane_event(full_ev, Q4_K_X8_ROWS, slice_rows, row_count - slice_rows); + const auto lane1 = make_row_sliced_lane_event( + full_ev, Q4_K_X8_ROWS, slice_rows, row_count - slice_rows); -#if defined(__aarch64__) && defined(__ARM_NEON) && defined(__ARM_FEATURE_DOTPROD) +#if defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD) CHECK(machine.process_event(lane0)); CHECK(machine.process_event(lane1)); for (size_t idx = 0; idx < packed_out.size(); ++idx) { @@ -3983,12 +4055,12 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x8_row_sliced_lane_views_are_su #endif } -TEST_CASE( - "kernel_aarch64_q6_k_prepared_q8_rhs_i8mm_matrix_x8_row_sliced_lane_views_are_supported") { - using emel::kernel::detail::quant::Q6_K_X8_ROWS; - using emel::kernel::detail::quant::QK_K; +TEST_CASE("kernel_aarch64_q6_k_prepared_q8_rhs_i8mm_matrix_x8_row_sliced_lane_" + "views_are_supported") { using emel::kernel::detail::quant::block_q6_k; using emel::kernel::detail::quant::block_q8_k; + using emel::kernel::detail::quant::Q6_K_X8_ROWS; + using emel::kernel::detail::quant::QK_K; constexpr uint64_t row_count = 16u; constexpr uint64_t slice_rows = Q6_K_X8_ROWS; @@ -3996,12 +4068,14 @@ TEST_CASE( constexpr uint64_t col_count = QK_K; constexpr uint64_t block_count = col_count / QK_K; - std::vector native_rows(static_cast(row_count * block_count)); + std::vector native_rows( + static_cast(row_count * block_count)); for (size_t row = 0; row < static_cast(row_count); ++row) { - auto & q6 = native_rows[row]; + auto &q6 = native_rows[row]; q6.d = 0x3c00u; for (size_t idx = 0; idx < q6.scales.size(); ++idx) { - const int32_t scale_value = static_cast((idx + row * 5u) % 15u) - 7; + const int32_t scale_value = + static_cast((idx + row * 5u) % 15u) - 7; q6.scales[idx] = static_cast(scale_value); } for (size_t idx = 0; idx < q6.ql.size(); ++idx) { @@ -4025,15 +4099,15 @@ TEST_CASE( std::vector rhs_q8(static_cast(rhs_rows * block_count)); for (size_t row = 0; row < static_cast(rhs_rows); ++row) { emel::kernel::detail::quant::quantize_row_q8_k_strided( - rhs_dense.data() + row * static_cast(col_count), - 1u, + rhs_dense.data() + row * static_cast(col_count), 1u, rhs_q8.data() + row * static_cast(block_count), static_cast(col_count)); } std::vector reference(static_cast(rhs_rows * row_count), 0.0f); for (size_t rhs_row = 0; rhs_row < static_cast(rhs_rows); ++rhs_row) { - for (size_t lhs_row = 0; lhs_row < static_cast(row_count); ++lhs_row) { + for (size_t lhs_row = 0; lhs_row < static_cast(row_count); + ++lhs_row) { reference[rhs_row * static_cast(row_count) + lhs_row] = emel::kernel::detail::dot_q6_k_q8_k_row_scalar( native_rows.data() + lhs_row * static_cast(block_count), @@ -4043,41 +4117,49 @@ TEST_CASE( } std::vector prepared_storage( - emel::kernel::detail::quant::prepared_q6_k_x8_q8_group_storage_bytes(col_count) * + emel::kernel::detail::quant::prepared_q6_k_x8_q8_group_storage_bytes( + col_count) * emel::kernel::detail::quant::packed_q6_k_x8_group_count(row_count)); REQUIRE(emel::kernel::detail::quant::pack_q6_k_rows_x8_q8_prepared( native_rows.data(), row_count, col_count, prepared_storage.data())); - std::vector prepared_out(static_cast(rhs_rows * row_count), 0.0f); + std::vector prepared_out(static_cast(rhs_rows * row_count), + 0.0f); aarch64_sm machine{}; const emel::kernel::event::op_mul_mat full_ev{ - .src0 = make_prepared_q6_k_x8_q8_src(prepared_storage.data(), col_count, row_count), + .src0 = make_prepared_q6_k_x8_q8_src(prepared_storage.data(), col_count, + row_count), .src1 = make_q8_k_x8_rhs_src(rhs_q8.data(), rhs_rows, col_count), - .dst = make_batch_major_dst(prepared_out.data(), dtype::f32, rhs_rows, row_count), + .dst = make_batch_major_dst(prepared_out.data(), dtype::f32, rhs_rows, + row_count), }; const auto lane0 = make_row_sliced_lane_event(full_ev, Q6_K_X8_ROWS, 0u, slice_rows); - const auto lane1 = - make_row_sliced_lane_event(full_ev, Q6_K_X8_ROWS, slice_rows, row_count - slice_rows); + const auto lane1 = make_row_sliced_lane_event( + full_ev, Q6_K_X8_ROWS, slice_rows, row_count - slice_rows); -#if defined(__aarch64__) && defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) +#if defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_MATMUL_INT8) CHECK(machine.process_event(lane0)); CHECK(machine.process_event(lane1)); for (size_t idx = 0; idx < prepared_out.size(); ++idx) { - CHECK(prepared_out[idx] == doctest::Approx(reference[idx]).epsilon(1.0e-5f)); + CHECK(prepared_out[idx] == + doctest::Approx(reference[idx]).epsilon(1.0e-5f)); } - CHECK(machine.optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count() == 2u); + CHECK(machine.optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count() == + 2u); #else CHECK_FALSE(machine.process_event(lane0)); CHECK_FALSE(machine.process_event(lane1)); #endif } -TEST_CASE("kernel_aarch64_q8_0_packed_bl8_matrix_x4_row_sliced_lane_views_are_supported") { +TEST_CASE("kernel_aarch64_q8_0_packed_bl8_matrix_x4_row_sliced_lane_views_are_" + "supported") { + using emel::kernel::detail::quant::block_q8_0; using emel::kernel::detail::quant::Q8_0_X4_ROWS; using emel::kernel::detail::quant::QK8_0; - using emel::kernel::detail::quant::block_q8_0; constexpr uint64_t row_count = 8u; constexpr uint64_t slice_rows = Q8_0_X4_ROWS; @@ -4085,15 +4167,18 @@ TEST_CASE("kernel_aarch64_q8_0_packed_bl8_matrix_x4_row_sliced_lane_views_are_su constexpr uint64_t col_count = QK8_0 * 8u; constexpr uint64_t block_count = col_count / QK8_0; - std::vector native_rows(static_cast(row_count * block_count)); + std::vector native_rows( + static_cast(row_count * block_count)); for (size_t row = 0; row < static_cast(row_count); ++row) { for (size_t block = 0; block < static_cast(block_count); ++block) { - auto & cell = native_rows[row * static_cast(block_count) + block]; + auto &cell = native_rows[row * static_cast(block_count) + block]; cell.d = emel::kernel::detail::quant::fp32_to_fp16( - 0.0078125f * static_cast(((row + 3u) * (block + 5u)) % 23u + 1u)); + 0.0078125f * + static_cast(((row + 3u) * (block + 5u)) % 23u + 1u)); for (size_t idx = 0; idx < cell.qs.size(); ++idx) { const int32_t centered = - static_cast(((row + 7u) * 17u + (block + 11u) * 13u + idx * 5u) % 255u) - + static_cast( + ((row + 7u) * 17u + (block + 11u) * 13u + idx * 5u) % 255u) - 127; cell.qs[idx] = static_cast(std::clamp(centered, -127, 127)); } @@ -4113,15 +4198,15 @@ TEST_CASE("kernel_aarch64_q8_0_packed_bl8_matrix_x4_row_sliced_lane_views_are_su std::vector rhs_q8(static_cast(rhs_rows * block_count)); for (size_t row = 0; row < static_cast(rhs_rows); ++row) { emel::kernel::detail::quant::quantize_row_q8_0_strided( - rhs_dense.data() + row * static_cast(col_count), - 1u, + rhs_dense.data() + row * static_cast(col_count), 1u, rhs_q8.data() + row * static_cast(block_count), static_cast(col_count)); } std::vector reference(static_cast(rhs_rows * row_count), 0.0f); for (size_t rhs_row = 0; rhs_row < static_cast(rhs_rows); ++rhs_row) { - for (size_t lhs_row = 0; lhs_row < static_cast(row_count); ++lhs_row) { + for (size_t lhs_row = 0; lhs_row < static_cast(row_count); + ++lhs_row) { reference[rhs_row * static_cast(row_count) + lhs_row] = emel::kernel::detail::dot_q8_0_q8_0_row_scalar( native_rows.data() + lhs_row * static_cast(block_count), @@ -4132,7 +4217,8 @@ TEST_CASE("kernel_aarch64_q8_0_packed_bl8_matrix_x4_row_sliced_lane_views_are_su std::vector packed_bl8( sizeof(emel::kernel::detail::quant::block_q8_0x4) * - emel::kernel::detail::quant::packed_q8_0_x4_group_count(row_count) * block_count); + emel::kernel::detail::quant::packed_q8_0_x4_group_count(row_count) * + block_count); std::vector rhs_packed_bl8( sizeof(emel::kernel::detail::quant::block_q8_0x4) * block_count); REQUIRE(emel::kernel::detail::quant::pack_q8_0_rows_x4_bl8( @@ -4140,20 +4226,25 @@ TEST_CASE("kernel_aarch64_q8_0_packed_bl8_matrix_x4_row_sliced_lane_views_are_su REQUIRE(emel::kernel::detail::quant::pack_q8_0_rows_x4_bl8( rhs_q8.data(), rhs_rows, col_count, rhs_packed_bl8.data())); - std::vector packed_out(static_cast(rhs_rows * row_count), 0.0f); + std::vector packed_out(static_cast(rhs_rows * row_count), + 0.0f); aarch64_sm machine{}; const emel::kernel::event::op_mul_mat full_ev{ - .src0 = make_packed_q8_0_x4_bl8_src(packed_bl8.data(), col_count, row_count), - .src1 = make_packed_q8_0_x4_bl8_rhs_src(rhs_packed_bl8.data(), rhs_rows, col_count), - .dst = make_batch_major_dst(packed_out.data(), dtype::f32, rhs_rows, row_count), + .src0 = + make_packed_q8_0_x4_bl8_src(packed_bl8.data(), col_count, row_count), + .src1 = make_packed_q8_0_x4_bl8_rhs_src(rhs_packed_bl8.data(), rhs_rows, + col_count), + .dst = make_batch_major_dst(packed_out.data(), dtype::f32, rhs_rows, + row_count), }; const auto lane0 = make_row_sliced_lane_event(full_ev, Q8_0_X4_ROWS, 0u, slice_rows); - const auto lane1 = - make_row_sliced_lane_event(full_ev, Q8_0_X4_ROWS, slice_rows, row_count - slice_rows); + const auto lane1 = make_row_sliced_lane_event( + full_ev, Q8_0_X4_ROWS, slice_rows, row_count - slice_rows); -#if defined(__aarch64__) && defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) +#if defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_MATMUL_INT8) CHECK(machine.process_event(lane0)); CHECK(machine.process_event(lane1)); for (size_t idx = 0; idx < packed_out.size(); ++idx) { @@ -4166,12 +4257,13 @@ TEST_CASE("kernel_aarch64_q8_0_packed_bl8_matrix_x4_row_sliced_lane_views_are_su #endif } -TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x4_row_sliced_lane_views_are_supported") { +TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x4_row_sliced_lane_views_are_" + "supported") { + using emel::kernel::detail::quant::block_q4_k; + using emel::kernel::detail::quant::block_q8_k; using emel::kernel::detail::quant::Q4_K_X8_ROWS; using emel::kernel::detail::quant::Q8_0_X4_ROWS; using emel::kernel::detail::quant::QK_K; - using emel::kernel::detail::quant::block_q4_k; - using emel::kernel::detail::quant::block_q8_k; constexpr uint64_t row_count = 16u; constexpr uint64_t slice_rows = Q4_K_X8_ROWS; @@ -4179,13 +4271,15 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x4_row_sliced_lane_views_are_su constexpr uint64_t col_count = QK_K; constexpr uint64_t block_count = col_count / QK_K; - std::vector native_rows(static_cast(row_count * block_count)); + std::vector native_rows( + static_cast(row_count * block_count)); for (size_t row = 0; row < static_cast(row_count); ++row) { - auto & q4 = native_rows[row]; + auto &q4 = native_rows[row]; q4.d = 0x3c00u; q4.dmin = static_cast(0x3800u + row * 0x0040u); for (size_t idx = 0; idx < q4.scales.size(); ++idx) { - q4.scales[idx] = static_cast((idx * (11u + row)) ^ (0x5au + row)); + q4.scales[idx] = + static_cast((idx * (11u + row)) ^ (0x5au + row)); } for (size_t idx = 0; idx < q4.qs.size(); ++idx) { q4.qs[idx] = static_cast((idx * (9u + row)) ^ (0x96u - row)); @@ -4205,15 +4299,15 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x4_row_sliced_lane_views_are_su std::vector rhs_q8(static_cast(rhs_rows * block_count)); for (size_t row = 0; row < static_cast(rhs_rows); ++row) { emel::kernel::detail::quant::quantize_row_q8_k_strided( - rhs_dense.data() + row * static_cast(col_count), - 1u, + rhs_dense.data() + row * static_cast(col_count), 1u, rhs_q8.data() + row * static_cast(block_count), static_cast(col_count)); } std::vector reference(static_cast(rhs_rows * row_count), 0.0f); for (size_t rhs_row = 0; rhs_row < static_cast(rhs_rows); ++rhs_row) { - for (size_t lhs_row = 0; lhs_row < static_cast(row_count); ++lhs_row) { + for (size_t lhs_row = 0; lhs_row < static_cast(row_count); + ++lhs_row) { reference[rhs_row * static_cast(row_count) + lhs_row] = emel::kernel::detail::dot_q4_k_q8_k_row_scalar( native_rows.data() + lhs_row * static_cast(block_count), @@ -4224,24 +4318,29 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x4_row_sliced_lane_views_are_su std::vector packed_bl8( sizeof(emel::kernel::detail::quant::block_q4_kx8) * - emel::kernel::detail::quant::packed_q4_k_x8_group_count(row_count) * block_count); + emel::kernel::detail::quant::packed_q4_k_x8_group_count(row_count) * + block_count); REQUIRE(emel::kernel::detail::quant::pack_q4_k_rows_x8_bl8( native_rows.data(), row_count, col_count, packed_bl8.data())); - std::vector packed_out(static_cast(rhs_rows * row_count), 0.0f); + std::vector packed_out(static_cast(rhs_rows * row_count), + 0.0f); aarch64_sm machine{}; const emel::kernel::event::op_mul_mat full_ev{ - .src0 = make_packed_q4_k_x8_bl8_src(packed_bl8.data(), col_count, row_count), + .src0 = + make_packed_q4_k_x8_bl8_src(packed_bl8.data(), col_count, row_count), .src1 = make_q8_k_x4_rhs_src(rhs_q8.data(), rhs_rows, col_count), - .dst = make_batch_major_dst(packed_out.data(), dtype::f32, rhs_rows, row_count), + .dst = make_batch_major_dst(packed_out.data(), dtype::f32, rhs_rows, + row_count), }; const auto lane0 = make_row_sliced_lane_event(full_ev, Q4_K_X8_ROWS, 0u, slice_rows); - const auto lane1 = - make_row_sliced_lane_event(full_ev, Q4_K_X8_ROWS, slice_rows, row_count - slice_rows); + const auto lane1 = make_row_sliced_lane_event( + full_ev, Q4_K_X8_ROWS, slice_rows, row_count - slice_rows); -#if defined(__aarch64__) && defined(__ARM_NEON) && defined(__ARM_FEATURE_DOTPROD) +#if defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD) CHECK(machine.process_event(lane0)); CHECK(machine.process_event(lane1)); for (size_t idx = 0; idx < packed_out.size(); ++idx) { @@ -4254,13 +4353,13 @@ TEST_CASE("kernel_aarch64_q4_k_packed_bl8_matrix_x4_row_sliced_lane_views_are_su #endif } -TEST_CASE( - "kernel_aarch64_q6_k_prepared_q8_rhs_i8mm_matrix_x4_row_sliced_lane_views_are_supported") { +TEST_CASE("kernel_aarch64_q6_k_prepared_q8_rhs_i8mm_matrix_x4_row_sliced_lane_" + "views_are_supported") { + using emel::kernel::detail::quant::block_q6_k; + using emel::kernel::detail::quant::block_q8_k; using emel::kernel::detail::quant::Q6_K_X8_ROWS; using emel::kernel::detail::quant::Q8_0_X4_ROWS; using emel::kernel::detail::quant::QK_K; - using emel::kernel::detail::quant::block_q6_k; - using emel::kernel::detail::quant::block_q8_k; constexpr uint64_t row_count = 16u; constexpr uint64_t slice_rows = Q6_K_X8_ROWS; @@ -4268,12 +4367,14 @@ TEST_CASE( constexpr uint64_t col_count = QK_K; constexpr uint64_t block_count = col_count / QK_K; - std::vector native_rows(static_cast(row_count * block_count)); + std::vector native_rows( + static_cast(row_count * block_count)); for (size_t row = 0; row < static_cast(row_count); ++row) { - auto & q6 = native_rows[row]; + auto &q6 = native_rows[row]; q6.d = 0x3c00u; for (size_t idx = 0; idx < q6.scales.size(); ++idx) { - const int32_t scale_value = static_cast((idx + row * 5u) % 15u) - 7; + const int32_t scale_value = + static_cast((idx + row * 5u) % 15u) - 7; q6.scales[idx] = static_cast(scale_value); } for (size_t idx = 0; idx < q6.ql.size(); ++idx) { @@ -4297,15 +4398,15 @@ TEST_CASE( std::vector rhs_q8(static_cast(rhs_rows * block_count)); for (size_t row = 0; row < static_cast(rhs_rows); ++row) { emel::kernel::detail::quant::quantize_row_q8_k_strided( - rhs_dense.data() + row * static_cast(col_count), - 1u, + rhs_dense.data() + row * static_cast(col_count), 1u, rhs_q8.data() + row * static_cast(block_count), static_cast(col_count)); } std::vector reference(static_cast(rhs_rows * row_count), 0.0f); for (size_t rhs_row = 0; rhs_row < static_cast(rhs_rows); ++rhs_row) { - for (size_t lhs_row = 0; lhs_row < static_cast(row_count); ++lhs_row) { + for (size_t lhs_row = 0; lhs_row < static_cast(row_count); + ++lhs_row) { reference[rhs_row * static_cast(row_count) + lhs_row] = emel::kernel::detail::dot_q6_k_q8_k_row_scalar( native_rows.data() + lhs_row * static_cast(block_count), @@ -4315,31 +4416,38 @@ TEST_CASE( } std::vector prepared_storage( - emel::kernel::detail::quant::prepared_q6_k_x8_q8_group_storage_bytes(col_count) * + emel::kernel::detail::quant::prepared_q6_k_x8_q8_group_storage_bytes( + col_count) * emel::kernel::detail::quant::packed_q6_k_x8_group_count(row_count)); REQUIRE(emel::kernel::detail::quant::pack_q6_k_rows_x8_q8_prepared( native_rows.data(), row_count, col_count, prepared_storage.data())); - std::vector prepared_out(static_cast(rhs_rows * row_count), 0.0f); + std::vector prepared_out(static_cast(rhs_rows * row_count), + 0.0f); aarch64_sm machine{}; const emel::kernel::event::op_mul_mat full_ev{ - .src0 = make_prepared_q6_k_x8_q8_src(prepared_storage.data(), col_count, row_count), + .src0 = make_prepared_q6_k_x8_q8_src(prepared_storage.data(), col_count, + row_count), .src1 = make_q8_k_x4_rhs_src(rhs_q8.data(), rhs_rows, col_count), - .dst = make_batch_major_dst(prepared_out.data(), dtype::f32, rhs_rows, row_count), + .dst = make_batch_major_dst(prepared_out.data(), dtype::f32, rhs_rows, + row_count), }; const auto lane0 = make_row_sliced_lane_event(full_ev, Q6_K_X8_ROWS, 0u, slice_rows); - const auto lane1 = - make_row_sliced_lane_event(full_ev, Q6_K_X8_ROWS, slice_rows, row_count - slice_rows); + const auto lane1 = make_row_sliced_lane_event( + full_ev, Q6_K_X8_ROWS, slice_rows, row_count - slice_rows); -#if defined(__aarch64__) && defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) +#if defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_MATMUL_INT8) CHECK(machine.process_event(lane0)); CHECK(machine.process_event(lane1)); for (size_t idx = 0; idx < prepared_out.size(); ++idx) { - CHECK(prepared_out[idx] == doctest::Approx(reference[idx]).epsilon(1.0e-5f)); + CHECK(prepared_out[idx] == + doctest::Approx(reference[idx]).epsilon(1.0e-5f)); } - CHECK(machine.optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count() == 2u); + CHECK(machine.optimized_q6_vector_prepared_q8_rhs_i8mm_dispatch_count() == + 2u); #else CHECK_FALSE(machine.process_event(lane0)); CHECK_FALSE(machine.process_event(lane1)); @@ -4610,8 +4718,8 @@ TEST_CASE("kernel_aarch64_detail_branch_paths") { using emel::kernel::detail::quant::block_q4_k; using emel::kernel::detail::quant::block_q6_k; - using emel::kernel::detail::quant::block_q8_k; using emel::kernel::detail::quant::block_q8_0; + using emel::kernel::detail::quant::block_q8_k; using emel::kernel::detail::quant::QK8_0; std::array q4_k_rows = {}; std::array q6_k_rows = {}; @@ -4772,25 +4880,28 @@ TEST_CASE("kernel_aarch64_detail_branch_paths") { .src1 = make_src(lhs, dtype::f32, 1u, 4u), .dst = make_dst(vector_out.data(), dtype::f32, 1u, 1u), }; - CHECK(emel::kernel::aarch64::detail:: - can_run_neon_mul_mat_f32_vector_request(f32_ev)); + CHECK(emel::kernel::aarch64::detail::can_run_neon_mul_mat_f32_vector_request( + f32_ev)); { auto bad = f32_ev; bad.src1.ne[0] = 2u; - CHECK_FALSE(emel::kernel::aarch64::detail:: - can_run_neon_mul_mat_f32_vector_request(bad)); + CHECK_FALSE( + emel::kernel::aarch64::detail::can_run_neon_mul_mat_f32_vector_request( + bad)); } { auto bad = f32_ev; bad.src0.nb[1] = bad.src0.nb[1] + sizeof(float); - CHECK_FALSE(emel::kernel::aarch64::detail:: - can_run_neon_mul_mat_f32_vector_request(bad)); + CHECK_FALSE( + emel::kernel::aarch64::detail::can_run_neon_mul_mat_f32_vector_request( + bad)); } const auto reject_f32 = [&](const auto mutate) { auto bad = f32_ev; mutate(bad); - CHECK_FALSE(emel::kernel::aarch64::detail:: - can_run_neon_mul_mat_f32_vector_request(bad)); + CHECK_FALSE( + emel::kernel::aarch64::detail::can_run_neon_mul_mat_f32_vector_request( + bad)); }; reject_f32([](auto &bad) { bad.src0.ne[0] = 0u; }); reject_f32([](auto &bad) { bad.src0.ne[1] = 0u; }); @@ -4807,8 +4918,10 @@ TEST_CASE("kernel_aarch64_detail_branch_paths") { reject_f32([](auto &bad) { bad.src1.type = dtype::q4_k; }); reject_f32([](auto &bad) { bad.dst.type = dtype::q4_k; }); reject_f32([](auto &bad) { bad.src0.nb[0] = sizeof(float) * 2u; }); - reject_f32([](auto &bad) { bad.src0.nb[2] = bad.src0.nb[2] + sizeof(float); }); - reject_f32([](auto &bad) { bad.src0.nb[3] = bad.src0.nb[3] + sizeof(float); }); + reject_f32( + [](auto &bad) { bad.src0.nb[2] = bad.src0.nb[2] + sizeof(float); }); + reject_f32( + [](auto &bad) { bad.src0.nb[3] = bad.src0.nb[3] + sizeof(float); }); emel::kernel::event::op_unary unary_ev{ .src0 = make_src(lhs, dtype::f32, 4), @@ -4865,8 +4978,8 @@ TEST_CASE("kernel_aarch64_q4_k_vector_q8_rhs_tail_rows_match_scalar") { std::array out = {}; const emel::kernel::event::op_mul_mat ev{ - .src0 = make_quantized_src(native_rows.data(), dtype::q4_k, QK_K, - row_count), + .src0 = + make_quantized_src(native_rows.data(), dtype::q4_k, QK_K, row_count), .src1 = make_q8_k_vector_src(rhs_q8.data(), QK_K), .dst = make_dst(out.data(), dtype::f32, 1u, row_count), }; @@ -5164,7 +5277,6 @@ TEST_CASE("kernel_aarch64_flash_attn_ext_uses_optimized_backend_path") { #endif } - TEST_CASE( "kernel_aarch64_flash_attn_ext_matches_shared_workspace_on_long_kv_spans") { #if !(defined(__aarch64__) || defined(__ARM_NEON)) diff --git a/tests/kernel/lifecycle_tests.cpp b/tests/kernel/lifecycle_tests.cpp index f36a706a..ba6e9880 100644 --- a/tests/kernel/lifecycle_tests.cpp +++ b/tests/kernel/lifecycle_tests.cpp @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -415,6 +417,8 @@ TEST_CASE("kernel_backends_accept_dispatch_event") { kernel_sm kernel_machine{}; emel::kernel::any any_machine{}; + CHECK(kernel_machine.kind() == emel::kernel::detect_host_kind()); + CHECK(any_machine.kind() == emel::kernel::detect_host_kind()); CHECK(x86_64_machine.process_event(event)); CHECK(aarch64_machine.process_event(event)); CHECK(kernel_machine.process_event(event)); @@ -705,6 +709,28 @@ TEST_CASE("kernel_detail_stride_paths_and_scalar_helpers") { CHECK_FALSE(emel::kernel::detail::execute_scalar(unsupported_ev)); } +TEST_CASE("kernel_soft_max_row_matches_ggml_arm64_neon_bits") { +#if defined(__aarch64__) && defined(__ARM_NEON) + std::array values = { + 0.25f, -0.5f, 1.25f, -3.0f, 2.5f, 0.0f, -1.5f, 0.75f, + 3.25f, -2.25f, 1.0f, 0.125f, -0.875f, 2.0f, -4.0f, 0.5f, + }; + constexpr std::array expected = { + 0x3caece97u, 0x3c25255eu, 0x3d6d965au, 0x3a58e566u, + 0x3e4f50b8u, 0x3c8823cbu, 0x3b7303e3u, 0x3d101aa1u, + 0x3edb717au, 0x3ae595a1u, 0x3d390880u, 0x3c9a4441u, + 0x3be3018fu, 0x3dfb7c76u, 0x399f954fu, 0x3ce074e5u, + }; + + emel::kernel::detail::soft_max_row_ggml( + static_cast(values.size()), values.data()); + + for (size_t index = 0; index < values.size(); ++index) { + CHECK(std::bit_cast(values[index]) == expected[index]); + } +#endif +} + TEST_CASE("kernel_backends_reject_quantized_dispatch_dtypes") { float src0[4] = {1.0f, 2.0f, 3.0f, 4.0f}; float src1[4] = {4.0f, 3.0f, 2.0f, 1.0f}; diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index e9708712..fb3ef23c 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -2,8 +2,8 @@ #include #include -#include #include +#include #include #include #include @@ -297,6 +297,14 @@ kv_store make_lm_kv(const lm_kv_options &options) { } store.i32_array("moshi.lm.delays", std::span{delays}); } + put_u32("moshi.lm.inference.dep_q", 2u); + put_u32("moshi.lm.inference.pre_text_silence_frames", 1u); + put_u32("moshi.lm.inference.post_text_silence_frames", 1u); + if (options.skip_key != "moshi.lm.inference.prompt_tokens") { + const std::array prompt_tokens = {3, 4, 5, 6, 7}; + store.i32_array("moshi.lm.inference.prompt_tokens", + std::span{prompt_tokens}); + } put_u32("moshi.lm.depformer.dim", 16u); put_u32("moshi.lm.depformer.num_heads", 2u); put_u32("moshi.lm.depformer.num_layers", 2u); @@ -373,12 +381,9 @@ uint64_t quant_storage_bytes(const int64_t cols, const int64_t rows, return blocks * block_bytes; } -void set_matrix_tensor(emel::model::data &model, - const std::string_view name, - const int32_t dtype, - const int64_t cols, - const int64_t rows, - const uint64_t data_size) { +void set_matrix_tensor(emel::model::data &model, const std::string_view name, + const int32_t dtype, const int64_t cols, + const int64_t rows, const uint64_t data_size) { auto *tensor = find_mutable_tensor(model, name); REQUIRE(tensor != nullptr); REQUIRE(cols > 0); @@ -389,12 +394,9 @@ void set_matrix_tensor(emel::model::data &model, tensor->data_size = data_size; } -void set_q4_k_matrix(emel::model::data &model, - const std::string_view name, - const int64_t cols, - const int64_t rows) { - REQUIRE(cols % static_cast(emel::kernel::detail::quant::QK_K) == - 0); +void set_q4_k_matrix(emel::model::data &model, const std::string_view name, + const int64_t cols, const int64_t rows) { + REQUIRE(cols % static_cast(emel::kernel::detail::quant::QK_K) == 0); set_matrix_tensor(model, name, emel::kernel::detail::dtype_q4_k, cols, rows, q4_k_storage_bytes(cols, rows)); } @@ -489,13 +491,13 @@ TEST_CASE("enriched mimi fixture loads hparams and contract") { CHECK(model.moshi_component_id == emel::model::data::moshi_component::mimi); CHECK(model.mimi.sample_rate == 24000); CHECK(model.mimi.frame_rate == doctest::Approx(12.5f)); - CHECK(model.mimi.n_q == 4); + CHECK(model.mimi.n_q == 2); CHECK(model.mimi.card == 32); CHECK(model.mimi.dim == 16); CHECK(model.mimi.codebook_dim == 8); CHECK(model.mimi.semantic_n_q == 1); CHECK(model.mimi.transformer_num_layers == 2); - CHECK(model.params.n_features == 4); + CHECK(model.params.n_features == 2); moshi::execution_contract contract = {}; REQUIRE(moshi::build_execution_contract(model, contract) == k_none); @@ -588,6 +590,31 @@ TEST_CASE("moshi lm hparams require the full metadata contract") { CHECK_FALSE(load_lm_hparams(make_lm_kv({.dep_q = 5}), *model)); } + SUBCASE("missing inference keys fail for personaplex lmgen") { + CHECK_FALSE(load_lm_hparams( + make_lm_kv({.skip_key = "moshi.lm.inference.dep_q"}), *model)); + CHECK_FALSE(load_lm_hparams( + make_lm_kv({.skip_key = "moshi.lm.inference.prompt_tokens"}), *model)); + } + + SUBCASE("depformer weight schedule metadata loads when present") { + auto store = make_lm_kv({}); + const std::array schedule = {0, 1, 1, 2}; + store.i32_array("moshi.lm.depformer.weights_per_step_schedule", + std::span{schedule}); + CHECK(load_lm_hparams(store, *model)); + CHECK(model->moshi_lm.depformer_weight_schedule_count == schedule.size()); + CHECK(model->moshi_lm.depformer_weight_schedule[2] == 1); + } + + SUBCASE("depformer weight schedule count must match dep_q") { + auto store = make_lm_kv({}); + const std::array schedule = {0, 1, 2}; + store.i32_array("moshi.lm.depformer.weights_per_step_schedule", + std::span{schedule}); + CHECK_FALSE(load_lm_hparams(store, *model)); + } + SUBCASE("missing depformer keys fail when dep_q is positive") { CHECK_FALSE(load_lm_hparams( make_lm_kv({.skip_key = "moshi.lm.depformer.dim"}), *model)); @@ -743,11 +770,11 @@ TEST_CASE("moshi lm contract accounts for supported dense tensor byte widths") { CAPTURE(entry.name); auto model = std::make_unique(*loaded.model); configure_q4_k_lm_contract(*model); - set_matrix_tensor( - *model, "lm.text_emb.weight", entry.dtype, model->moshi_lm.dim, - model->moshi_lm.text_card + 1, - dense_storage_bytes(model->moshi_lm.dim, model->moshi_lm.text_card + 1, - entry.element_bytes)); + set_matrix_tensor(*model, "lm.text_emb.weight", entry.dtype, + model->moshi_lm.dim, model->moshi_lm.text_card + 1, + dense_storage_bytes(model->moshi_lm.dim, + model->moshi_lm.text_card + 1, + entry.element_bytes)); CHECK(moshi::validate_execution_contract(*model) == k_none); auto *tensor = find_mutable_tensor(*model, "lm.text_emb.weight"); @@ -769,12 +796,8 @@ TEST_CASE("moshi lm contract accepts supported gguf tensor layouts") { int32_t dtype = 0; }; const std::array cases{ - dtype_case{"f32", 0}, - dtype_case{"q4_0", 2}, - dtype_case{"q8_0", 8}, - dtype_case{"q2_k", 10}, - dtype_case{"q3_k", 11}, - dtype_case{"q4_k", 12}, + dtype_case{"f32", 0}, dtype_case{"q4_0", 2}, dtype_case{"q8_0", 8}, + dtype_case{"q2_k", 10}, dtype_case{"q3_k", 11}, dtype_case{"q4_k", 12}, dtype_case{"q6_k", 14}, }; @@ -782,19 +805,17 @@ TEST_CASE("moshi lm contract accepts supported gguf tensor layouts") { CAPTURE(entry.name); auto model = std::make_unique(*loaded.model); configure_q4_k_lm_contract(*model); - const auto layout = - emel::gguf::loader::detail::ggml_layout( - static_cast(entry.dtype)); + const auto layout = emel::gguf::loader::detail::ggml_layout( + static_cast(entry.dtype)); REQUIRE(layout.block_size > 0u); REQUIRE(layout.type_size > 0u); - REQUIRE(static_cast(model->moshi_lm.dim) % - layout.block_size == + REQUIRE(static_cast(model->moshi_lm.dim) % layout.block_size == 0u); - set_matrix_tensor( - *model, "lm.text_emb.weight", entry.dtype, model->moshi_lm.dim, - model->moshi_lm.text_card + 1, - quant_storage_bytes(model->moshi_lm.dim, model->moshi_lm.text_card + 1, - layout.block_size, layout.type_size)); + set_matrix_tensor(*model, "lm.text_emb.weight", entry.dtype, + model->moshi_lm.dim, model->moshi_lm.text_card + 1, + quant_storage_bytes(model->moshi_lm.dim, + model->moshi_lm.text_card + 1, + layout.block_size, layout.type_size)); CHECK(moshi::validate_execution_contract(*model) == k_none); auto *tensor = find_mutable_tensor(*model, "lm.text_emb.weight"); @@ -816,38 +837,36 @@ TEST_CASE("moshi lm contract rejects unsupported known gguf tensor layouts") { int32_t dtype = 0; }; const std::array cases{ - dtype_case{"f16", 1}, dtype_case{"q4_1", 3}, - dtype_case{"q5_0", 6}, - dtype_case{"q5_1", 7}, dtype_case{"q8_1", 9}, - dtype_case{"q5_k", 13}, dtype_case{"q8_k", 15}, - dtype_case{"iq2_xxs", 16}, dtype_case{"iq2_xs", 17}, - dtype_case{"iq3_xxs", 18}, dtype_case{"iq1_s", 19}, - dtype_case{"iq4_nl", 20}, dtype_case{"iq3_s", 21}, - dtype_case{"iq2_s", 22}, dtype_case{"iq4_xs", 23}, - dtype_case{"i8", 24}, dtype_case{"i16", 25}, - dtype_case{"i32", 26}, dtype_case{"i64", 27}, - dtype_case{"f64", 28}, dtype_case{"iq1_m", 29}, - dtype_case{"bf16", 30}, dtype_case{"tq1_0", 34}, - dtype_case{"tq2_0", 35}, dtype_case{"mxfp4", 39}, + dtype_case{"f16", 1}, dtype_case{"q4_1", 3}, + dtype_case{"q5_0", 6}, dtype_case{"q5_1", 7}, + dtype_case{"q8_1", 9}, dtype_case{"q5_k", 13}, + dtype_case{"q8_k", 15}, dtype_case{"iq2_xxs", 16}, + dtype_case{"iq2_xs", 17}, dtype_case{"iq3_xxs", 18}, + dtype_case{"iq1_s", 19}, dtype_case{"iq4_nl", 20}, + dtype_case{"iq3_s", 21}, dtype_case{"iq2_s", 22}, + dtype_case{"iq4_xs", 23}, dtype_case{"i8", 24}, + dtype_case{"i16", 25}, dtype_case{"i32", 26}, + dtype_case{"i64", 27}, dtype_case{"f64", 28}, + dtype_case{"iq1_m", 29}, dtype_case{"bf16", 30}, + dtype_case{"tq1_0", 34}, dtype_case{"tq2_0", 35}, + dtype_case{"mxfp4", 39}, }; for (const auto &entry : cases) { CAPTURE(entry.name); auto model = std::make_unique(*loaded.model); configure_q4_k_lm_contract(*model); - const auto layout = - emel::gguf::loader::detail::ggml_layout( - static_cast(entry.dtype)); + const auto layout = emel::gguf::loader::detail::ggml_layout( + static_cast(entry.dtype)); REQUIRE(layout.block_size > 0u); REQUIRE(layout.type_size > 0u); - REQUIRE(static_cast(model->moshi_lm.dim) % - layout.block_size == + REQUIRE(static_cast(model->moshi_lm.dim) % layout.block_size == 0u); - set_matrix_tensor( - *model, "lm.text_emb.weight", entry.dtype, model->moshi_lm.dim, - model->moshi_lm.text_card + 1, - quant_storage_bytes(model->moshi_lm.dim, model->moshi_lm.text_card + 1, - layout.block_size, layout.type_size)); + set_matrix_tensor(*model, "lm.text_emb.weight", entry.dtype, + model->moshi_lm.dim, model->moshi_lm.text_card + 1, + quant_storage_bytes(model->moshi_lm.dim, + model->moshi_lm.text_card + 1, + layout.block_size, layout.type_size)); CHECK(moshi::validate_execution_contract(*model) != k_none); } } @@ -1012,9 +1031,10 @@ bool append_cloned_tensor(emel::model::data &model, return false; } -} // namespace +} // namespace -TEST_CASE("mimi contract validation rejects rvq split counts past the codec cap") { +TEST_CASE( + "mimi contract validation rejects rvq split counts past the codec cap") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { return; @@ -1036,7 +1056,8 @@ TEST_CASE("mimi contract validation rejects rvq split counts past the codec cap" CHECK(moshi::validate_execution_contract(model) != k_none); } -TEST_CASE("mimi contract validation rejects transformer layers past the codec cap") { +TEST_CASE( + "mimi contract validation rejects transformer layers past the codec cap") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { return; @@ -1048,17 +1069,22 @@ TEST_CASE("mimi contract validation rejects transformer layers past the codec ca // layers 2..16 for both families so every probed tensor exists. auto &model = *loaded.model; static constexpr const char *k_layer_tensors[] = { - "norm1.weight", "norm1.bias", - "norm2.weight", "norm2.bias", - "layer_scale_1.scale", "layer_scale_2.scale", - "self_attn.in_projs.0.weight", "self_attn.out_projs.0.weight", - "linear1.weight", "linear2.weight", + "norm1.weight", + "norm1.bias", + "norm2.weight", + "norm2.bias", + "layer_scale_1.scale", + "layer_scale_2.scale", + "self_attn.in_projs.0.weight", + "self_attn.out_projs.0.weight", + "linear1.weight", + "linear2.weight", }; for (const char *family : {"encoder_transformer", "decoder_transformer"}) { for (int layer = 2; layer <= 16; ++layer) { for (const char *suffix : k_layer_tensors) { - const std::string source = std::string("mimi.") + family + - ".transformer.layers.1." + suffix; + const std::string source = + std::string("mimi.") + family + ".transformer.layers.1." + suffix; const std::string clone = std::string("mimi.") + family + ".transformer.layers." + std::to_string(layer) + "." + suffix; @@ -1135,7 +1161,8 @@ TEST_CASE("mimi contract validation rejects a mixed f16 conv class") { CHECK(moshi::validate_execution_contract(model) != k_none); } -TEST_CASE("mimi contract validation requires f16 rvq projections in the f16 class") { +TEST_CASE( + "mimi contract validation requires f16 rvq projections in the f16 class") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { return; @@ -1154,7 +1181,8 @@ TEST_CASE("mimi contract validation requires f16 rvq projections in the f16 clas const std::string_view name{model.name_storage.data() + tensor.name_offset, tensor.name_length}; const bool non_transposed_conv = - (name.starts_with("mimi.encoder.") || name.starts_with("mimi.decoder.") || + (name.starts_with("mimi.encoder.") || + name.starts_with("mimi.decoder.") || name.starts_with("mimi.downsample.")) && name.ends_with("conv.conv.weight") && name.find("convtr") == std::string_view::npos; @@ -1164,7 +1192,7 @@ TEST_CASE("mimi contract validation requires f16 rvq projections in the f16 clas tensor.type = k_dtype_f16; flipped += 1; } - REQUIRE(flipped >= 25u); // 14 encoder + 10 decoder + downsample + REQUIRE(flipped >= 25u); // 14 encoder + 10 decoder + downsample CHECK(moshi::validate_execution_contract(model) != k_none); } @@ -1196,7 +1224,8 @@ TEST_CASE("mimi contract validation rejects oversized conv geometry extents") { CHECK(moshi::validate_execution_contract(model) != k_none); } -TEST_CASE("mimi contract validation rejects a frame length off the stride chain") { +TEST_CASE( + "mimi contract validation rejects a frame length off the stride chain") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { return; @@ -1205,11 +1234,12 @@ TEST_CASE("mimi contract validation rejects a frame length off the stride chain" // The fixed encoder/downsample stride chain reduces exactly 1920 samples // to one token; a positive finite frame rate producing any other frame // length validated here and then failed plan_seanet/plan_codec. - loaded.model->mimi.frame_rate = 25.0f; // 24000 / 25 = 960 samples + loaded.model->mimi.frame_rate = 25.0f; // 24000 / 25 = 960 samples CHECK(moshi::validate_execution_contract(*loaded.model) != k_none); } -TEST_CASE("mimi contract validation rejects codebook extents past the codec cap") { +TEST_CASE( + "mimi contract validation rejects codebook extents past the codec cap") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { return; @@ -1237,7 +1267,8 @@ TEST_CASE("mimi contract validation rejects codebook extents past the codec cap" CHECK(moshi::validate_execution_contract(model) != k_none); } -TEST_CASE("mimi contract validation rejects non-float tensors the binder consumes") { +TEST_CASE( + "mimi contract validation rejects non-float tensors the binder consumes") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { return; @@ -1266,17 +1297,17 @@ TEST_CASE("mimi contract validation rejects non-float tensors the binder consume }; SUBCASE("bf16 transformer vector") { - REQUIRE(flip_type( - "mimi.encoder_transformer.transformer.layers.1.norm2.bias", - k_dtype_bf16)); + REQUIRE( + flip_type("mimi.encoder_transformer.transformer.layers.1.norm2.bias", + k_dtype_bf16)); } SUBCASE("bf16 seanet conv in the f32 class") { REQUIRE(flip_type("mimi.decoder.model.0.conv.conv.weight", k_dtype_bf16)); } SUBCASE("q8_0 rvq codebook") { - REQUIRE(flip_type( - "mimi.quantizer.rvq_first.vq.layers.0._codebook.embedding", - k_dtype_q8_0)); + REQUIRE( + flip_type("mimi.quantizer.rvq_first.vq.layers.0._codebook.embedding", + k_dtype_q8_0)); } CHECK(moshi::validate_execution_contract(model) != k_none); } @@ -1298,12 +1329,12 @@ TEST_CASE("mimi contract validation rejects mixed transformer mlp widths") { tensor.name_length}; if (name == "mimi.encoder_transformer.transformer.layers.1.linear1.weight") { - tensor.dims[1] = 1; // storage stays over-sized, width shrinks + tensor.dims[1] = 1; // storage stays over-sized, width shrinks narrowed = true; } if (name == "mimi.encoder_transformer.transformer.layers.1.linear2.weight") { - tensor.dims[0] = 1; // keep linear2 consistent with the narrowed layer + tensor.dims[0] = 1; // keep linear2 consistent with the narrowed layer } } REQUIRE(narrowed); @@ -1380,7 +1411,8 @@ TEST_CASE("mimi contract validation requires the fixed seanet topology") { CHECK(moshi::validate_execution_contract(model) != k_none); } -TEST_CASE("mimi contract validation rejects q8 classes with misaligned widths") { +TEST_CASE( + "mimi contract validation rejects q8 classes with misaligned widths") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { return; @@ -1402,7 +1434,7 @@ TEST_CASE("mimi contract validation rejects q8 classes with misaligned widths") name.find("linear2.weight") != std::string_view::npos || name.find("_proj.weight") != std::string_view::npos; if (projection && name.starts_with("mimi.")) { - tensor.type = 8; // q8_0 + tensor.type = 8; // q8_0 flipped += 1; } } @@ -1470,9 +1502,7 @@ TEST_CASE("mimi contract validation requires the rvq projections") { const size_t underscore = name.find("input_proj") + 5u; model.name_storage[tensor.name_offset + underscore] = 'x'; } - SUBCASE("wrong projection element count") { - tensor.dims[0] += 1; - } + SUBCASE("wrong projection element count") { tensor.dims[0] += 1; } corrupted = true; } REQUIRE(corrupted); @@ -1502,9 +1532,10 @@ TEST_CASE("mimi contract validation requires every acoustic rvq codebook") { // bind_rvq_split consumes every acoustic level 0..n_q-semantic_n_q-1 with // the full {codebook_dim, card} shape; corrupt the intermediate one (level - // 1 of 0..2 in the tiny fixture) so a last-index-only or existence-only - // probe would still pass while initialization fails. + // 1 of 0..2 after declaring the full tiny raw count) so a last-index-only + // or existence-only probe would still pass while initialization fails. auto &model = *loaded.model; + model.mimi.n_q = 4; bool corrupted = false; for (uint32_t idx = 0; idx < model.n_tensors; ++idx) { auto &tensor = model.tensors[idx]; @@ -1519,9 +1550,7 @@ TEST_CASE("mimi contract validation requires every acoustic rvq codebook") { const size_t digit = name.find("layers.1") + 7u; model.name_storage[tensor.name_offset + digit] = '9'; } - SUBCASE("wrong intermediate codebook shape") { - tensor.dims[1] += 1; - } + SUBCASE("wrong intermediate codebook shape") { tensor.dims[1] += 1; } corrupted = true; } REQUIRE(corrupted); diff --git a/tests/models/README.md b/tests/models/README.md index 2d863436..c78e0b2e 100644 --- a/tests/models/README.md +++ b/tests/models/README.md @@ -349,21 +349,22 @@ same-host ARM comparison matrix in Phase `59.1.1`. intermediate). - `moshi-tiny-lm-raw.gguf` is intentionally metadata-less (zero GGUF KV entries, moshi.cpp cache style) and is used to prove emel rejects unconverted moshi GGUFs. + - SHA256: - - `moshi-tiny-config.json`: `9808917cb929a06319033c86083b2589dcf5f8ee8314db0e78319c13cf61b58c` + - `moshi-tiny-config.json`: `7e6fbcacaa7ce6279fb8731cb01456f371781dc6b17c6e2308212d08b7f8ec0e` - `moshi-tokenizer-tiny.model`: `5ed25a383b9e3034941550f8b67d360d4178792a88f3f06b35ffba4417bc58e5` - `moshi-tiny-lm-raw.gguf`: `06e5824e6b586956147e388caf27c6dd52053cdb2ab2a1e4190ddb64bd0dab23` - - `moshi-tiny-lm.gguf`: `c83570ad540fed7a7390178046c161cf719dbf1b080c1421dec0a0af91c4f1bf` - - `mimi-tiny.gguf`: `92873fc4a6127f10a6798c03d3f0ce805ab2fa5544ca4d0b1efce996f72f0821` + - `moshi-tiny-lm.gguf`: `28cc6cd14d7fe8a2954b887e89d1b0d36dcb7fec0c295e21df51e1e15fa2cd8c` + - `mimi-tiny.gguf`: `518693f7b8d261fb41b2a018518dc1d64dbb505d7f869e996605a83d66d4af0f` (v1.28 M2 update: carries the full tiny-scale mimi_v0_1 SEANet topology — base 4 channels doubling to 64, kernel = 2×stride stage convs, resnet blocks, depthwise [4,1,16] upsample — so the codec compute layer can run complete encode/decode chains against it) - - `mimi-tiny-f16.gguf`: `011485af3e45a02b3e58b85f65d333681fa5adae8324738981f66dfe5556c5e3` + - `mimi-tiny-f16.gguf`: `3880b627a5b352a2ce1cf0a3a26ceca190a1ffff4773dda8213afc071dca75c1` (f16 operand-class variant: conv/projection weights stored f16 like the real Mimi artifact, driving the codec machines' guard_conv_f16 rows and the f16 im2col/mul_mat and raw-f16 RVQ projection paths) - - `mimi-tiny-q8.gguf`: `f0fc70d70556d23e89cae440b63f3dfa2a4385393f229f1fc3f908f75b1ee869` + - `mimi-tiny-q8.gguf`: `f5919a3eb852772c67a6a913ccc2ee960d162f79949d8a96dcf5d847c3c44412` (q8_0 operand-class variant: dim/codebook_dim widened to one q8 block of 32 and the transformer + RVQ projections quantized by the converter's `--quantize q8_0` path, driving guard_proj_q8 / guard_class_q8 rows and @@ -372,7 +373,7 @@ same-host ARM comparison matrix in Phase `59.1.1`. - Modeled contract (tiny scale, not real weights): PersonaPlex-shaped `lm` component (dim `32`, `2` layers/`2` heads, `n_q=4`, `dep_q=4`, `card=32`, `text_card=64`, depformer dim `16`/`2` layers), Mimi-shaped `mimi` component (dim `16`, - codebook_dim `8`, `2`-layer codec transformers), and a PersonaPlex `voice` + active `n_q=2`, codebook_dim `8`, `2`-layer codec transformers), and a PersonaPlex `voice` prompt component (`voice.embeddings` + `voice.cache`). - Loader/runtime boundary note: these fixtures prove converter output, moshi architecture registration, hparam binding, and execution-contract validation only; diff --git a/tests/models/mimi-tiny-f16.gguf b/tests/models/mimi-tiny-f16.gguf index d8fe4c45..097efa0d 100644 --- a/tests/models/mimi-tiny-f16.gguf +++ b/tests/models/mimi-tiny-f16.gguf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:011485af3e45a02b3e58b85f65d333681fa5adae8324738981f66dfe5556c5e3 +oid sha256:3880b627a5b352a2ce1cf0a3a26ceca190a1ffff4773dda8213afc071dca75c1 size 327872 diff --git a/tests/models/mimi-tiny-q8.gguf b/tests/models/mimi-tiny-q8.gguf index e2ac4458..5770b121 100644 --- a/tests/models/mimi-tiny-q8.gguf +++ b/tests/models/mimi-tiny-q8.gguf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0fc70d70556d23e89cae440b63f3dfa2a4385393f229f1fc3f908f75b1ee869 +oid sha256:f5919a3eb852772c67a6a913ccc2ee960d162f79949d8a96dcf5d847c3c44412 size 514976 diff --git a/tests/models/mimi-tiny.gguf b/tests/models/mimi-tiny.gguf index f354dd8c..2bd7319d 100644 --- a/tests/models/mimi-tiny.gguf +++ b/tests/models/mimi-tiny.gguf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92873fc4a6127f10a6798c03d3f0ce805ab2fa5544ca4d0b1efce996f72f0821 +oid sha256:518693f7b8d261fb41b2a018518dc1d64dbb505d7f869e996605a83d66d4af0f size 443232 diff --git a/tests/models/moshi-tiny-config.json b/tests/models/moshi-tiny-config.json index da6d7f54..b9ef478f 100644 --- a/tests/models/moshi-tiny-config.json +++ b/tests/models/moshi-tiny-config.json @@ -31,6 +31,16 @@ "depformer_gating": "silu", "depformer_pos_emb": "none", "depformer_weights_per_step": true, + "inference_dep_q": 2, + "inference_prompt_tokens": [ + 3, + 4, + 5, + 6, + 7 + ], + "inference_pre_text_silence_frames": 1, + "inference_post_text_silence_frames": 1, "cross_attention": false, "model_type": "personaplex", "tokenizer_name": "moshi-tokenizer-tiny.model" diff --git a/tests/models/moshi-tiny-lm.gguf b/tests/models/moshi-tiny-lm.gguf index 001dde9b..88be114d 100644 --- a/tests/models/moshi-tiny-lm.gguf +++ b/tests/models/moshi-tiny-lm.gguf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c83570ad540fed7a7390178046c161cf719dbf1b080c1421dec0a0af91c4f1bf -size 251744 +oid sha256:28cc6cd14d7fe8a2954b887e89d1b0d36dcb7fec0c295e21df51e1e15fa2cd8c +size 251968 diff --git a/tests/speech/codec/mimi_detail_tests.cpp b/tests/speech/codec/mimi_detail_tests.cpp index 64a06ea1..ce1c2eac 100644 --- a/tests/speech/codec/mimi_detail_tests.cpp +++ b/tests/speech/codec/mimi_detail_tests.cpp @@ -232,7 +232,7 @@ TEST_CASE("mimi codec binds and encodes deterministic frames") { bound_codec codec_state{}; REQUIRE(bind_or_fail(*loaded.model, codec_state)); CHECK(codec_state.runtime.frame_samples == 1920); - CHECK(codec_state.runtime.n_q == 4); + CHECK(codec_state.runtime.n_q == 2); CHECK(codec_state.runtime.dim == 16); const auto pcm = deterministic_pcm(codec_state.runtime.frame_samples); @@ -277,6 +277,23 @@ TEST_CASE("mimi codec decodes codes back to a full frame of audio") { std::span{pcm})); CHECK(all_finite(pcm.data(), pcm.size())); + codec::reset_streaming_state(codec_state.runtime, codec_state.streaming); + const size_t partial_count = + std::min(codes.size() - 1u, + static_cast( + codec_state.runtime.quantizer.semantic.level_count + 1)); + REQUIRE(partial_count > 0u); + REQUIRE(partial_count < codes.size()); + std::vector partial_pcm( + static_cast(codec_state.runtime.frame_samples), 0.0f); + CHECK(codec::validate_codes_in_range( + codec_state.runtime, + std::span{codes.data(), partial_count})); + REQUIRE(decode_frame(codec_state, + std::span{codes.data(), partial_count}, + std::span{partial_pcm})); + CHECK(all_finite(partial_pcm.data(), partial_pcm.size())); + // out-of-range codes are rejected by the pure request validator the // quantizer/facade guards route on (the compute path never sees them) std::vector bad_codes = codes; diff --git a/tests/speech/codec/mimi_lifecycle_tests.cpp b/tests/speech/codec/mimi_lifecycle_tests.cpp index 424be2b0..8cc75a91 100644 --- a/tests/speech/codec/mimi_lifecycle_tests.cpp +++ b/tests/speech/codec/mimi_lifecycle_tests.cpp @@ -1,7 +1,7 @@ #include "doctest/doctest.h" -#include #include +#include #include #include #include @@ -228,7 +228,7 @@ TEST_CASE("mimi codec facade initializes, encodes, and decodes frames") { CHECK(err == emel::error::cast(mimi::error::none)); check_session_ready(machine); CHECK(g_frame_samples == 1920); - CHECK(g_n_q == 4); + CHECK(g_n_q == 2); const auto pcm = deterministic_pcm(g_frame_samples); std::vector codes(static_cast(g_n_q), -1); @@ -256,6 +256,28 @@ TEST_CASE("mimi codec facade initializes, encodes, and decodes frames") { check_session_ready(machine); CHECK(g_decode_done_count == 1u); + REQUIRE(machine.process_event(mimi::event::reset_stream{})); + const size_t partial_count = + std::min(codes.size() - 1u, + static_cast(loaded.model->mimi.semantic_n_q + 1)); + REQUIRE(partial_count > 0u); + REQUIRE(partial_count < codes.size()); + std::vector partial_decoded(static_cast(g_frame_samples), + 0.0f); + mimi::event::decode_frame partial_decode{ + std::span{codes.data(), partial_count}, + std::span{partial_decoded}}; + partial_decode.error_out = &err; + partial_decode.on_done = emel::callback::from<&on_decode_frame_done>(); + REQUIRE(machine.process_event(partial_decode)); + CHECK(err == emel::error::cast(mimi::error::none)); + check_session_ready(machine); + CHECK(g_decode_done_count == 2u); + for (const float sample : partial_decoded) { + CHECK(std::isfinite(sample)); + } + // stream reset replays the exact same codes for the same first frame std::vector replay(codes.size(), -1); REQUIRE(machine.process_event(mimi::event::reset_stream{})); @@ -410,9 +432,9 @@ TEST_CASE("mimi codec initialize rejects out-of-contract model metadata") { // 256-float buffer while the declared extents describe 2^64 elements. for (uint32_t index = 0u; index < loaded.model->n_tensors; ++index) { auto &tensor = loaded.model->tensors[index]; - const std::string_view name{ - loaded.model->name_storage.data() + tensor.name_offset, - tensor.name_length}; + const std::string_view name{loaded.model->name_storage.data() + + tensor.name_offset, + tensor.name_length}; if (name == "mimi.encoder_transformer.transformer.layers.0.self_attn." "out_projs.0.weight") { tensor.n_dims = 2; @@ -428,9 +450,9 @@ TEST_CASE("mimi codec initialize rejects out-of-contract model metadata") { // time with no error channel, so the plan must reject the q8 class. for (uint32_t index = 0u; index < loaded.model->n_tensors; ++index) { auto &tensor = loaded.model->tensors[index]; - const std::string_view name{ - loaded.model->name_storage.data() + tensor.name_offset, - tensor.name_length}; + const std::string_view name{loaded.model->name_storage.data() + + tensor.name_offset, + tensor.name_length}; const bool projection = name.find("self_attn.in_projs.0.weight") != std::string_view::npos || name.find("self_attn.out_projs.0.weight") != std::string_view::npos || @@ -438,7 +460,7 @@ TEST_CASE("mimi codec initialize rejects out-of-contract model metadata") { name.find("linear2.weight") != std::string_view::npos || name.find("_proj.weight") != std::string_view::npos; if (projection && name.starts_with("mimi.")) { - tensor.type = 8; // q8_0 + tensor.type = 8; // q8_0 } } expect_bind_failed(*loaded.model); @@ -457,9 +479,9 @@ TEST_CASE("mimi codec initialize rejects out-of-contract model metadata") { // one-tap upsample kernel against stride 2 would index outside it. for (uint32_t index = 0u; index < loaded.model->n_tensors; ++index) { auto &tensor = loaded.model->tensors[index]; - const std::string_view name{ - loaded.model->name_storage.data() + tensor.name_offset, - tensor.name_length}; + const std::string_view name{loaded.model->name_storage.data() + + tensor.name_offset, + tensor.name_length}; if (name == "mimi.upsample.convtr.convtr.convtr.weight") { tensor.dims[0] = 1; } @@ -470,9 +492,9 @@ TEST_CASE("mimi codec initialize rejects out-of-contract model metadata") { SUBCASE("seanet transposed layer kernel shorter than its stride") { for (uint32_t index = 0u; index < loaded.model->n_tensors; ++index) { auto &tensor = loaded.model->tensors[index]; - const std::string_view name{ - loaded.model->name_storage.data() + tensor.name_offset, - tensor.name_length}; + const std::string_view name{loaded.model->name_storage.data() + + tensor.name_offset, + tensor.name_length}; if (name.find("decoder.model.") != std::string_view::npos && name.find(".convtr.convtr.weight") != std::string_view::npos) { tensor.dims[0] = 1; @@ -504,9 +526,9 @@ TEST_CASE("mimi codec initialize rejects out-of-contract model metadata") { // span negative in the sizing accounting. for (uint32_t index = 0u; index < loaded.model->n_tensors; ++index) { auto &tensor = loaded.model->tensors[index]; - const std::string_view name{ - loaded.model->name_storage.data() + tensor.name_offset, - tensor.name_length}; + const std::string_view name{loaded.model->name_storage.data() + + tensor.name_offset, + tensor.name_length}; if (name.find("encoder.model.") != std::string_view::npos && name.find(".conv.conv.weight") != std::string_view::npos && name.find(".block.") == std::string_view::npos) { @@ -519,9 +541,9 @@ TEST_CASE("mimi codec initialize rejects out-of-contract model metadata") { SUBCASE("downsample conv kernel shorter than its stride") { for (uint32_t index = 0u; index < loaded.model->n_tensors; ++index) { auto &tensor = loaded.model->tensors[index]; - const std::string_view name{ - loaded.model->name_storage.data() + tensor.name_offset, - tensor.name_length}; + const std::string_view name{loaded.model->name_storage.data() + + tensor.name_offset, + tensor.name_length}; if (name == "mimi.downsample.conv.conv.conv.weight") { tensor.dims[0] = 1; } @@ -667,8 +689,9 @@ TEST_CASE("mimi codec facade rejects malformed frame requests explicitly") { std::span{codes}}; bad_encode.error_out = &err; g_encode_error_count = 0; - bad_encode.on_error = emel::callback::from<&on_encode_frame_error>(); + bad_encode.on_error = + emel::callback::from< + &on_encode_frame_error>(); CHECK_FALSE(machine.process_event(bad_encode)); CHECK(g_encode_error_count == 1u); CHECK(err == emel::error::cast(mimi::error::request_shape)); @@ -681,8 +704,9 @@ TEST_CASE("mimi codec facade rejects malformed frame requests explicitly") { std::span{short_pcm_out}}; bad_decode.error_out = &err; g_decode_error_count = 0; - bad_decode.on_error = emel::callback::from<&on_decode_frame_error>(); + bad_decode.on_error = + emel::callback::from< + &on_decode_frame_error>(); CHECK_FALSE(machine.process_event(bad_decode)); CHECK(g_decode_error_count == 1u); CHECK(err == emel::error::cast(mimi::error::request_shape)); @@ -751,11 +775,10 @@ TEST_CASE("mimi codec facade streams the f16 and q8 operand-class fixtures") { emel::error::type err = emel::error::cast(mimi::error::none); g_frame_samples = 0; g_n_q = 0; - mimi::event::initialize init{*loaded.model, - std::span{arenas.prepared}, - std::span{arenas.state}, - std::span{arenas.workspace}, - std::span{arenas.frame}}; + mimi::event::initialize init{ + *loaded.model, std::span{arenas.prepared}, + std::span{arenas.state}, std::span{arenas.workspace}, + std::span{arenas.frame}}; init.error_out = &err; init.on_done = emel::callback::from<&on_initialize_done>(); @@ -851,8 +874,7 @@ TEST_CASE("mimi child actors report validation errors when driven directly") { { quantizer::sm machine{}; emel::error::type err = emel::error::cast(quantizer::error::none); - quantizer::event::encode ev{unbound_runtime, - std::span{tiny_buf}, + quantizer::event::encode ev{unbound_runtime, std::span{tiny_buf}, std::span{tiny_codes}, std::span{tiny_buf}}; ev.error_out = &err; @@ -860,10 +882,9 @@ TEST_CASE("mimi child actors report validation errors when driven directly") { CHECK(err == emel::error::cast(quantizer::error::runtime_unbound)); err = emel::error::cast(quantizer::error::none); - quantizer::event::decode dev{unbound_runtime, - std::span{tiny_codes}, - std::span{tiny_buf}, - std::span{tiny_buf}}; + quantizer::event::decode dev{ + unbound_runtime, std::span{tiny_codes}, + std::span{tiny_buf}, std::span{tiny_buf}}; dev.error_out = &err; CHECK_FALSE(machine.process_event(dev)); CHECK(err == emel::error::cast(quantizer::error::runtime_unbound)); @@ -893,12 +914,13 @@ TEST_CASE("mimi child actors report validation errors when driven directly") { // pcm shorter than one frame -> request_shape encoder::sm machine{}; emel::error::type err = emel::error::cast(encoder::error::none); - encoder::event::encode ev{runtime, - streaming, - std::span{pcm.data(), pcm.size() - 1u}, - std::span{frame}, - std::span{workspace}, - std::span{latent}}; + encoder::event::encode ev{ + runtime, + streaming, + std::span{pcm.data(), pcm.size() - 1u}, + std::span{frame}, + std::span{workspace}, + std::span{latent}}; ev.error_out = &err; CHECK_FALSE(machine.process_event(ev)); CHECK(err == emel::error::cast(encoder::error::request_shape)); @@ -933,13 +955,13 @@ TEST_CASE("mimi child actors report validation errors when driven directly") { // latent narrower than dim -> request_shape decoder::sm machine{}; emel::error::type err = emel::error::cast(decoder::error::none); - decoder::event::decode ev{runtime, - streaming, - std::span{latent.data(), - latent.size() - 1u}, - std::span{frame}, - std::span{workspace}, - std::span{pcm}}; + decoder::event::decode ev{ + runtime, + streaming, + std::span{latent.data(), latent.size() - 1u}, + std::span{frame}, + std::span{workspace}, + std::span{pcm}}; ev.error_out = &err; CHECK_FALSE(machine.process_event(ev)); CHECK(err == emel::error::cast(decoder::error::request_shape)); @@ -974,11 +996,9 @@ TEST_CASE("mimi child actors report validation errors when driven directly") { // code_range quantizer::sm machine{}; emel::error::type err = emel::error::cast(quantizer::error::none); - quantizer::event::encode ev{runtime, - std::span{latent.data(), - latent.size() - 1u}, - std::span{codes}, - std::span{workspace}}; + quantizer::event::encode ev{ + runtime, std::span{latent.data(), latent.size() - 1u}, + std::span{codes}, std::span{workspace}}; ev.error_out = &err; CHECK_FALSE(machine.process_event(ev)); CHECK(err == emel::error::cast(quantizer::error::request_shape)); @@ -986,8 +1006,7 @@ TEST_CASE("mimi child actors report validation errors when driven directly") { err = emel::error::cast(quantizer::error::none); std::vector bad_codes(codes.size(), 0); bad_codes[0] = runtime.quantizer.codebook_entries; - quantizer::event::decode dev{runtime, - std::span{bad_codes}, + quantizer::event::decode dev{runtime, std::span{bad_codes}, std::span{latent}, std::span{workspace}}; dev.error_out = &err; diff --git a/tests/speech/generator/moshi_lifecycle_tests.cpp b/tests/speech/generator/moshi_lifecycle_tests.cpp new file mode 100644 index 00000000..3699f270 --- /dev/null +++ b/tests/speech/generator/moshi_lifecycle_tests.cpp @@ -0,0 +1,2100 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../../memory/recording_kv_actor.hpp" +#include "emel/gguf/loader/detail.hpp" +#include "emel/gguf/loader/events.hpp" +#include "emel/gguf/loader/sm.hpp" +#include "emel/model/detail.hpp" +#include "emel/model/moshi/detail.hpp" +#include "emel/speech/codec/mimi/any.hpp" +#include "emel/speech/generator/moshi/any.hpp" +#include "emel/speech/generator/moshi/executor/any.hpp" + +namespace { + +namespace moshi = emel::speech::generator::moshi; +namespace moshi_executor = emel::speech::generator::moshi::executor; +namespace mimi = emel::speech::codec::mimi; +namespace model_moshi = emel::model::moshi::detail; + +inline constexpr emel::error::type k_no_error = + emel::error::cast(moshi::error::none); + +int32_t g_mimi_frame_samples = 0; +int32_t g_mimi_n_q = 0; + +std::filesystem::path repo_root() { +#ifdef EMEL_TEST_REPO_ROOT + return std::filesystem::path{EMEL_TEST_REPO_ROOT}; +#else + return std::filesystem::current_path(); +#endif +} + +std::filesystem::path moshi_fixture_path(const std::string_view name) { + return repo_root() / "tests" / "models" / std::string{name}; +} + +std::vector read_binary_file(const std::filesystem::path &path) { + std::ifstream file{path, std::ios::binary}; + REQUIRE(file.good()); + file.seekg(0, std::ios::end); + const std::streamoff size = file.tellg(); + REQUIRE(size > 0); + std::vector bytes(static_cast(size)); + file.seekg(0, std::ios::beg); + file.read(reinterpret_cast(bytes.data()), size); + REQUIRE(file.good()); + return bytes; +} + +void noop_probe_done(const emel::gguf::loader::events::probe_done &) {} +void noop_probe_error(const emel::gguf::loader::events::probe_error &) {} +void noop_bind_done(const emel::gguf::loader::events::bind_done &) {} +void noop_bind_error(const emel::gguf::loader::events::bind_error &) {} +void noop_parse_done(const emel::gguf::loader::events::parse_done &) {} +void noop_parse_error(const emel::gguf::loader::events::parse_error &) {} + +void on_mimi_initialized(const mimi::events::initialize_done &done) { + g_mimi_frame_samples = done.frame_samples; + g_mimi_n_q = done.n_q; +} + +std::vector deterministic_pcm(const int32_t frame_samples) { + std::vector pcm(static_cast(frame_samples), 0.0f); + for (int32_t index = 0; index < frame_samples; ++index) { + const float carrier = static_cast((index % 109) - 54) / 54.0f; + const float envelope = + 0.35f + 0.65f * static_cast((index / 160) % 2); + pcm[static_cast(index)] = 0.08f * envelope * carrier; + } + return pcm; +} + +struct loaded_moshi_fixture { + std::vector file_bytes = {}; + std::vector kv_arena = {}; + std::vector kv_entries = {}; + std::unique_ptr model = {}; + + emel::model::detail::kv_binding binding() const { + return emel::model::detail::kv_binding{ + .arena = std::span{kv_arena}, + .entries = std::span{kv_entries}, + }; + } +}; + +struct recording_graph_executor { + int32_t call_count = 0; + int32_t external_embedding_count = 0; + int32_t first_sequence_length = -1; + int32_t second_sequence_length = -1; + int32_t last_sequence_length = -1; + int32_t first_forced_text_token = -1; + int32_t last_forced_text_token = -1; + float first_embedding_sample = 0.0f; + std::array first_input = {}; + std::array last_input = {}; +}; + +struct temporal_kv_probe { + int32_t call_count = 0; + int32_t sequence_id = -1; + int32_t sequence_length = -1; + std::vector key_cache = {}; + std::vector value_cache = {}; + std::vector layer_offsets = {}; +}; + +struct depformer_kv_probe { + int32_t call_count = 0; + int32_t sequence_id = -1; + int32_t sequence_length = -1; + int32_t offset = 0; + std::vector key_cache = {}; + std::vector value_cache = {}; + std::vector layer_offsets = {}; +}; + +struct moshi_callback_probe { + int32_t done_count = 0; + int32_t error_count = 0; + int32_t n_q = -1; + int32_t dep_q = -1; + int32_t prompt_frames = -1; + int32_t remaining_frames = -1; + bool complete = false; + bool produced = false; + emel::error::type err = k_no_error; + const void *request = nullptr; + + void on_generator_initialize_done( + const moshi::events::initialize_done &done) noexcept { + ++done_count; + request = done.request; + n_q = done.n_q; + dep_q = done.dep_q; + } + + void on_generator_initialize_error( + const moshi::events::initialize_error &error) noexcept { + ++error_count; + request = error.request; + err = error.err; + } + + void on_generator_load_voice_done( + const moshi::events::load_voice_done &done) noexcept { + ++done_count; + request = done.request; + prompt_frames = done.prompt_frames; + } + + void on_generator_load_voice_error( + const moshi::events::load_voice_error &error) noexcept { + ++error_count; + request = error.request; + err = error.err; + } + + void on_generator_prefill_voice_done( + const moshi::events::prefill_voice_done &done) noexcept { + ++done_count; + request = done.request; + complete = done.complete; + remaining_frames = done.remaining_frames; + } + + void on_generator_prefill_voice_error( + const moshi::events::prefill_voice_error &error) noexcept { + ++error_count; + request = error.request; + err = error.err; + } + + void on_generator_begin_prompt_done( + const moshi::events::begin_personaplex_prompt_done &done) noexcept { + ++done_count; + request = done.request; + remaining_frames = done.remaining_frames; + } + + void on_generator_begin_prompt_error( + const moshi::events::begin_personaplex_prompt_error &error) noexcept { + ++error_count; + request = error.request; + err = error.err; + } + + void on_generator_prefill_prompt_done( + const moshi::events::prefill_personaplex_prompt_done &done) noexcept { + ++done_count; + request = done.request; + complete = done.complete; + remaining_frames = done.remaining_frames; + } + + void on_generator_prefill_prompt_error( + const moshi::events::prefill_personaplex_prompt_error &error) noexcept { + ++error_count; + request = error.request; + err = error.err; + } + + void on_generator_step_done(const moshi::events::step_done &done) noexcept { + ++done_count; + request = done.request; + produced = done.produced; + } + + void + on_generator_step_error(const moshi::events::step_error &error) noexcept { + ++error_count; + request = error.request; + err = error.err; + } + + void on_executor_initialize_done( + const moshi_executor::events::initialize_done &done) noexcept { + ++done_count; + request = done.request; + n_q = done.n_q; + dep_q = done.dep_q; + } + + void on_executor_initialize_error( + const moshi_executor::events::initialize_error &error) noexcept { + ++error_count; + request = error.request; + err = error.err; + } +}; + +bool dispatch_recording_graph(void *executor_ptr, + const moshi::event::graph_step &step) { + auto &executor = *static_cast(executor_ptr); + ++executor.call_count; + if (!step.input_embedding.empty()) { + ++executor.external_embedding_count; + if (executor.external_embedding_count == 1) { + executor.first_forced_text_token = step.forced_text_token; + executor.first_embedding_sample = step.input_embedding[0]; + } + } + std::fill(executor.last_input.begin(), executor.last_input.end(), -99); + std::copy(step.input_sequence.begin(), step.input_sequence.end(), + executor.last_input.begin()); + executor.last_sequence_length = step.memory_snapshot.sequence_length(0); + executor.last_forced_text_token = step.forced_text_token; + if (executor.call_count == 1) { + std::fill(executor.first_input.begin(), executor.first_input.end(), -99); + std::copy(step.input_sequence.begin(), step.input_sequence.end(), + executor.first_input.begin()); + executor.first_sequence_length = step.memory_snapshot.sequence_length(0); + } + if (executor.call_count == 2) { + executor.second_sequence_length = step.memory_snapshot.sequence_length(0); + } + if (step.error_out != nullptr) { + *step.error_out = k_no_error; + } + step.text_token_out = 100 + executor.call_count; + for (size_t index = 0; index < step.audio_tokens_out.size(); ++index) { + step.audio_tokens_out[index] = static_cast( + 1000 + executor.call_count * 10 + static_cast(index)); + } + return true; +} + +bool temporal_kv_probe_bind(void *cache_ptr, const emel::model::data &model, + const emel::memory::view::snapshot &snapshot, + const int32_t sequence_id, + moshi_executor::detail::temporal_kv_view &view) { + auto &probe = *static_cast(cache_ptr); + ++probe.call_count; + probe.sequence_id = sequence_id; + probe.sequence_length = snapshot.sequence_length(sequence_id); + const int32_t position_capacity = model.moshi_lm.context; + const int32_t kv_dim = model.moshi_lm.dim; + const int32_t layer_count = model.moshi_lm.num_layers; + REQUIRE(position_capacity > 0); + REQUIRE(kv_dim > 0); + REQUIRE(layer_count > 0); + const size_t per_layer = + static_cast(position_capacity) * static_cast(kv_dim); + probe.layer_offsets.resize(static_cast(layer_count)); + for (int32_t layer = 0; layer < layer_count; ++layer) { + probe.layer_offsets[static_cast(layer)] = + static_cast(layer) * per_layer; + } + probe.key_cache.assign(static_cast(layer_count) * per_layer, 0u); + probe.value_cache.assign(probe.key_cache.size(), 0u); + view.key_cache = + std::span{probe.key_cache.data(), probe.key_cache.size()}; + view.value_cache = + std::span{probe.value_cache.data(), probe.value_cache.size()}; + view.layer_cache_offsets = probe.layer_offsets; + view.layer_count = layer_count; + view.position_capacity = position_capacity; + view.block_tokens = snapshot.block_tokens > 0 ? snapshot.block_tokens : 16; + view.kv_dim = kv_dim; + return true; +} + +bool depformer_kv_probe_bind(void *cache_ptr, const emel::model::data &model, + const emel::memory::view::snapshot &snapshot, + const int32_t sequence_id, + moshi_executor::detail::depformer_kv_view &view) { + auto &probe = *static_cast(cache_ptr); + ++probe.call_count; + probe.sequence_id = sequence_id; + probe.sequence_length = snapshot.sequence_length(sequence_id); + const int32_t position_capacity = model.moshi_lm.depformer_context; + const int32_t kv_dim = model.moshi_lm.depformer_dim; + const int32_t layer_count = model.moshi_lm.depformer_num_layers; + REQUIRE(position_capacity > 0); + REQUIRE(kv_dim > 0); + REQUIRE(layer_count > 0); + const size_t per_layer = + static_cast(position_capacity) * static_cast(kv_dim); + if (probe.key_cache.empty()) { + probe.layer_offsets.resize(static_cast(layer_count)); + for (int32_t layer = 0; layer < layer_count; ++layer) { + probe.layer_offsets[static_cast(layer)] = + static_cast(layer) * per_layer; + } + probe.key_cache.assign(static_cast(layer_count) * per_layer, 0u); + probe.value_cache.assign(probe.key_cache.size(), 0u); + } + view.key_cache = + std::span{probe.key_cache.data(), probe.key_cache.size()}; + view.value_cache = + std::span{probe.value_cache.data(), probe.value_cache.size()}; + view.layer_cache_offsets = probe.layer_offsets; + view.offset = &probe.offset; + view.layer_count = layer_count; + view.position_capacity = position_capacity; + view.block_tokens = 1; + view.kv_dim = kv_dim; + return true; +} + +void materialize_tensor_names_from_file(emel::model::data &model, + const std::vector &file) { + model.name_bytes_used = 0; + for (uint32_t index = 0; index < model.n_tensors; ++index) { + auto &tensor = model.tensors[index]; + const size_t source_offset = static_cast(tensor.name_offset); + const size_t length = static_cast(tensor.name_length); + REQUIRE(source_offset + length <= file.size()); + REQUIRE(static_cast(model.name_bytes_used) + length <= + model.name_storage.size()); + std::copy_n(file.data() + source_offset, length, + model.name_storage.data() + model.name_bytes_used); + tensor.name_offset = model.name_bytes_used; + model.name_bytes_used += static_cast(length); + } +} + +loaded_moshi_fixture load_fixture_or_skip(const std::string_view name) { + const auto fixture_path = moshi_fixture_path(name); + if (!std::filesystem::exists(fixture_path)) { + MESSAGE("skipping moshi fixture test because fixture is missing: " + << fixture_path.string()); + return {}; + } + + loaded_moshi_fixture loaded{}; + loaded.model = std::make_unique(); + loaded.file_bytes = read_binary_file(fixture_path); + + emel::gguf::loader::sm loader{}; + emel::gguf::loader::requirements requirements{}; + REQUIRE(loader.process_event(emel::gguf::loader::event::probe{ + std::span{loaded.file_bytes}, + requirements, + emel::gguf::loader::event::probe_done_fn::from<&noop_probe_done>(), + emel::gguf::loader::event::probe_error_fn::from<&noop_probe_error>(), + })); + + const uint64_t arena_bytes = + emel::gguf::loader::detail::required_kv_arena_bytes(requirements); + REQUIRE(arena_bytes != UINT64_MAX); + loaded.kv_arena.resize(static_cast(arena_bytes)); + loaded.kv_entries.resize(requirements.kv_count); + loaded.model->n_tensors = requirements.tensor_count; + + REQUIRE(loader.process_event(emel::gguf::loader::event::bind_storage{ + std::span{loaded.kv_arena}, + std::span{loaded.kv_entries}, + std::span{loaded.model->tensors.data(), + loaded.model->n_tensors}, + emel::gguf::loader::event::bind_done_fn::from<&noop_bind_done>(), + emel::gguf::loader::event::bind_error_fn::from<&noop_bind_error>(), + })); + REQUIRE(loader.process_event(emel::gguf::loader::event::parse{ + std::span{loaded.file_bytes}, + emel::gguf::loader::event::parse_done_fn::from<&noop_parse_done>(), + emel::gguf::loader::event::parse_error_fn::from<&noop_parse_error>(), + })); + REQUIRE(emel::model::detail::load_hparams_from_gguf(loaded.binding(), + *loaded.model)); + loaded.model->weights_data = loaded.file_bytes.data(); + loaded.model->weights_size = loaded.file_bytes.size(); + materialize_tensor_names_from_file(*loaded.model, loaded.file_bytes); + return loaded; +} + +} // namespace + +TEST_CASE("speech_moshi_generator_rejects_step_before_initialize") { + moshi::sm generator{}; + std::array input = {0, 0, 0, 0}; + std::array output = {}; + int32_t text_token = -1; + emel::error::type err = k_no_error; + + moshi::event::step step{std::span{input}, + std::span{output}, text_token}; + step.error_out = &err; + + CHECK_FALSE(generator.process_event(step)); + CHECK(err == emel::error::cast(moshi::error::not_initialized)); +} + +TEST_CASE("speech_moshi_generator_rejects_non_lm_model_contract") { + auto model = std::make_unique(); + model->moshi_component_id = emel::model::data::moshi_component::mimi; + moshi::sm generator{}; + emel::error::type err = k_no_error; + + moshi::event::initialize init{*model}; + init.error_out = &err; + + CHECK_FALSE(generator.process_event(init)); + CHECK(err == emel::error::cast(moshi::error::bind_failed)); +} + +TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + REQUIRE(model_moshi::validate_execution_contract(*fixture.model) == + emel::error::cast(emel::model::loader::error::none)); + + emel::memory::test::recording_kv_actor kv{}; + moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv)}; + emel::error::type err = k_no_error; + + moshi::event::initialize init{*fixture.model}; + init.max_sequences = 2; + init.max_blocks = 16; + init.block_tokens = 4; + init.error_out = &err; + + REQUIRE(generator.process_event(init)); + CHECK(err == k_no_error); + CHECK(kv.reserve_count == 1); + CHECK(kv.allocate_sequence_count == 1); +} + +TEST_CASE("speech_moshi_generator_personaplex_uses_model_inference_codebooks") { + auto model = std::make_unique(); + model->moshi_lm.n_q = 16; + model->moshi_lm.dep_q = 16; + model->moshi_lm.inference_dep_q = 8; + model->moshi_lm.text_padding_id = 3; + model->moshi_lm.depformer_weights_per_step = true; + model->moshi_lm.delay_count = 17; + model->moshi_lm.inference_prompt_token_count = 17; + model->moshi_lm.inference_prompt_tokens[0] = 3; + model->moshi_lm.delays[0] = 0; + for (uint32_t index = 1; index < model->moshi_lm.delay_count; ++index) { + model->moshi_lm.delays[index] = 1; + model->moshi_lm.inference_prompt_tokens[index] = + static_cast(index); + } + + moshi::event::initialize init{*model}; + moshi::event::initialize_ctx init_ctx{}; + moshi::event::initialize_run run{init, init_ctx}; + moshi::action::context ctx{}; + + moshi::action::effect_bind_contract{}(run, ctx); + CHECK(moshi::guard::guard_personaplex_lmgen{}(run, ctx)); + moshi::action::effect_configure_personaplex_lmgen{}(run, ctx); + + CHECK(ctx.lmgen.generated_dep_q == 16); + CHECK(ctx.lmgen.delayed_dep_q == model->moshi_lm.inference_dep_q); + CHECK(ctx.lmgen.needed_tokens == 8); + CHECK(ctx.lmgen.cache_row_count == 4); + + auto snapshot = std::make_unique(); + moshi::event::step_ctx step_ctx{*snapshot}; + std::array prompt_tail = {}; + std::array output = {}; + int32_t text_token = -1; + moshi::event::step step{std::span{prompt_tail}, + std::span{output}, text_token}; + moshi::event::step_run step_run{step, step_ctx}; + + CHECK(moshi::guard::guard_step_request_valid{}(step_run, ctx)); + + ctx.lmgen.offset = 5; + step_ctx.generated_dep_q = ctx.lmgen.generated_dep_q; + step_ctx.delayed_dep_q = ctx.lmgen.delayed_dep_q; + for (int32_t row = 0; row < ctx.lmgen.cache_row_count; ++row) { + for (int32_t column = 0; column < ctx.lmgen.codebook_count; ++column) { + moshi::detail::cache_at(ctx.lmgen, row, column) = column * 10 + row; + } + } + for (int32_t index = 0; index < ctx.lmgen.generated_dep_q; ++index) { + step_ctx.audio_tokens[static_cast(index)] = 1000 + index; + } + + moshi::action::effect_collect_delayed_output{}(step_run, ctx); + + CHECK(text_token == 0); + for (int32_t index = 0; index < ctx.lmgen.delayed_dep_q; ++index) { + CHECK(output[static_cast(index)] == (index + 1) * 10 + 1); + } +} + +TEST_CASE( + "speech_moshi_generator_loads_personaplex_voice_and_prefills_prompt") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + auto voice = load_fixture_or_skip("moshi-tiny-voice.gguf"); + if (fixture.model == nullptr || voice.model == nullptr) { + return; + } + + emel::memory::test::recording_kv_actor kv{}; + recording_graph_executor graph{}; + moshi::sm generator{ + emel::memory::hybrid::bind_kv_actor(kv), + moshi::action::bind_graph_executor(&graph, dispatch_recording_graph)}; + emel::error::type err = k_no_error; + + moshi::event::initialize init{*fixture.model}; + init.max_blocks = 32; + init.block_tokens = 4; + init.error_out = &err; + REQUIRE(generator.process_event(init)); + CHECK(err == k_no_error); + + const int32_t prompt_frames = 5; + moshi::event::load_voice load{*voice.model}; + load.error_out = &err; + REQUIRE(generator.process_event(load)); + CHECK(err == k_no_error); + + std::array output = {}; + int32_t text_token = -1; + bool produced = true; + moshi::event::step blocked_step{ + std::span{}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + blocked_step.error_out = &err; + blocked_step.produced_out = &produced; + CHECK_FALSE(generator.process_event(blocked_step)); + CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); + + for (int32_t index = 0; index < prompt_frames; ++index) { + bool complete = true; + int32_t remaining = -1; + emel::error::type graph_err = emel::error::cast(moshi::error::none); + err = k_no_error; + moshi::event::prefill_voice prefill{}; + prefill.error_out = &err; + prefill.graph_error_out = &graph_err; + prefill.complete_out = &complete; + prefill.remaining_frames_out = &remaining; + REQUIRE(generator.process_event(prefill)); + CHECK(err == k_no_error); + CHECK(graph_err == k_no_error); + CHECK(complete == (index + 1 == prompt_frames)); + CHECK(remaining == prompt_frames - index - 1); + } + + CHECK(graph.external_embedding_count == prompt_frames); + CHECK(graph.first_forced_text_token == + fixture.model->moshi_lm.text_padding_id); + CHECK(graph.first_embedding_sample != 0.0f); + CHECK(kv.allocate_slots_count >= prompt_frames); + CHECK(kv.capture_view_count >= prompt_frames); +} + +TEST_CASE("speech_moshi_generator_loads_personaplex_voice_embedding_dtypes") { + auto snapshot = std::make_unique(); + moshi::event::prefill_voice prefill{}; + moshi::event::prefill_voice_ctx prefill_ctx{*snapshot}; + moshi::event::prefill_voice_run prefill_run{prefill, prefill_ctx}; + moshi::action::context ctx{}; + emel::model::data::tensor_record tensor{}; + std::array data = {0x3c00u, 0x4000u, 0x4200u, 0x4400u}; + tensor.data = data.data(); + tensor.dims[0] = 2; + tensor.dims[3] = 2; + ctx.voice.contract.voice.embeddings.tensor = &tensor; + ctx.voice.embedding_dim = 2; + ctx.voice.prompt_frame_index = 1; + + tensor.type = emel::kernel::detail::dtype_f16; + moshi::action::effect_load_voice_embedding_frame_f16{}(prefill_run, ctx); + CHECK(prefill_ctx.embedding_frame_ok); + CHECK(prefill_ctx.embedding_frame[0] != 0.0f); + CHECK(prefill_ctx.embedding_frame[1] != 0.0f); + + prefill_ctx.embedding_frame_ok = false; + prefill_ctx.embedding_frame[0] = 0.0f; + prefill_ctx.embedding_frame[1] = 0.0f; + tensor.type = emel::kernel::detail::dtype_bf16; + moshi::action::effect_load_voice_embedding_frame_bf16{}(prefill_run, ctx); + CHECK(prefill_ctx.embedding_frame_ok); + CHECK(prefill_ctx.embedding_frame[0] != 0.0f); + CHECK(prefill_ctx.embedding_frame[1] != 0.0f); +} + +TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" + "generation") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + auto voice = load_fixture_or_skip("moshi-tiny-voice.gguf"); + if (fixture.model == nullptr || voice.model == nullptr) { + return; + } + + emel::memory::test::recording_kv_actor kv{}; + recording_graph_executor graph{}; + moshi::sm generator{ + emel::memory::hybrid::bind_kv_actor(kv), + moshi::action::bind_graph_executor(&graph, dispatch_recording_graph)}; + emel::error::type err = k_no_error; + + moshi::event::initialize init{*fixture.model}; + init.max_blocks = 48; + init.block_tokens = 4; + init.error_out = &err; + REQUIRE(generator.process_event(init)); + CHECK(err == k_no_error); + + moshi::event::load_voice load{*voice.model}; + load.error_out = &err; + REQUIRE(generator.process_event(load)); + CHECK(err == k_no_error); + + const int32_t prompt_frames = 5; + for (int32_t index = 0; index < prompt_frames; ++index) { + bool complete = false; + int32_t remaining = -1; + moshi::event::prefill_voice prefill{}; + prefill.error_out = &err; + prefill.complete_out = &complete; + prefill.remaining_frames_out = &remaining; + REQUIRE(generator.process_event(prefill)); + CHECK(err == k_no_error); + CHECK(complete == (index + 1 == prompt_frames)); + CHECK(remaining == prompt_frames - index - 1); + } + + const int32_t needed_tokens = (fixture.model->moshi_lm.n_q + 1) - + fixture.model->moshi_lm.inference_dep_q - 1; + REQUIRE(needed_tokens >= 0); + std::array input = {}; + std::array output = {}; + std::fill(input.begin(), input.end(), 0); + int32_t text_token = -1; + bool produced = true; + err = k_no_error; + moshi::event::step blocked_step{ + std::span{input.data(), + static_cast(needed_tokens)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + blocked_step.error_out = &err; + blocked_step.produced_out = &produced; + CHECK_FALSE(generator.process_event(blocked_step)); + CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); + + err = k_no_error; + moshi::event::begin_personaplex_prompt begin{}; + begin.text_token_count = 2; + begin.pre_text_silence_frames = 1; + begin.post_text_silence_frames = 1; + begin.error_out = &err; + REQUIRE(generator.process_event(begin)); + CHECK(err == k_no_error); + + const std::array prompt_text_tokens = {-1, 42, 43, -1}; + const std::array expected_text_inputs = {3, 42, 43, 3}; + for (int32_t index = 0; index < 4; ++index) { + bool complete = true; + int32_t remaining = -1; + emel::error::type graph_err = emel::error::cast(moshi::error::none); + err = k_no_error; + moshi::event::prefill_personaplex_prompt prefill{}; + prefill.text_token = prompt_text_tokens[static_cast(index)]; + prefill.error_out = &err; + prefill.graph_error_out = &graph_err; + prefill.complete_out = &complete; + prefill.remaining_frames_out = &remaining; + REQUIRE(generator.process_event(prefill)); + CHECK(err == k_no_error); + CHECK(graph_err == k_no_error); + CHECK(complete == (index == 3)); + CHECK(remaining == 3 - index); + CHECK(graph.last_input[0] == + expected_text_inputs[static_cast(index)]); + CHECK(graph.last_forced_text_token == -1); + } + + CHECK(graph.external_embedding_count == prompt_frames); + CHECK(graph.call_count == prompt_frames + 4); + CHECK(kv.allocate_slots_count >= prompt_frames + 4); + CHECK(kv.capture_view_count >= prompt_frames + 4); + + text_token = -1; + produced = true; + err = k_no_error; + emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); + moshi::event::step first_step{ + std::span{input.data(), + static_cast(needed_tokens)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + first_step.error_out = &err; + first_step.graph_error_out = &graph_err; + first_step.produced_out = &produced; + REQUIRE(generator.process_event(first_step)); + CHECK(err == k_no_error); + CHECK(graph_err == k_no_error); + CHECK(graph.call_count == prompt_frames + 5); +} + +TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" + "prompt") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + auto voice = load_fixture_or_skip("moshi-tiny-voice.gguf"); + if (fixture.model == nullptr || voice.model == nullptr) { + return; + } + + emel::memory::test::recording_kv_actor kv{}; + recording_graph_executor graph{}; + moshi::sm generator{ + emel::memory::hybrid::bind_kv_actor(kv), + moshi::action::bind_graph_executor(&graph, dispatch_recording_graph)}; + emel::error::type err = k_no_error; + + moshi::event::initialize init{*fixture.model}; + init.max_blocks = 48; + init.block_tokens = 4; + init.error_out = &err; + REQUIRE(generator.process_event(init)); + CHECK(err == k_no_error); + + moshi::event::load_voice load{*voice.model}; + load.error_out = &err; + REQUIRE(generator.process_event(load)); + CHECK(err == k_no_error); + + const int32_t prompt_frames = 5; + for (int32_t index = 0; index < prompt_frames; ++index) { + bool complete = false; + moshi::event::prefill_voice prefill{}; + prefill.error_out = &err; + prefill.complete_out = &complete; + REQUIRE(generator.process_event(prefill)); + CHECK(err == k_no_error); + CHECK(complete == (index + 1 == prompt_frames)); + } + + moshi::event::begin_personaplex_prompt begin{}; + begin.error_out = &err; + err = k_no_error; + REQUIRE(generator.process_event(begin)); + CHECK(err == k_no_error); + + const int32_t needed_tokens = (fixture.model->moshi_lm.n_q + 1) - + fixture.model->moshi_lm.inference_dep_q - 1; + REQUIRE(needed_tokens >= 0); + std::array input = {}; + std::array output = {}; + std::fill(input.begin(), input.end(), 0); + int32_t text_token = -1; + bool produced = false; + emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); + moshi::event::step step{ + std::span{input.data(), + static_cast(needed_tokens)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + step.error_out = &err; + step.graph_error_out = &graph_err; + step.produced_out = &produced; + + err = k_no_error; + CHECK_FALSE(generator.process_event(step)); + CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); + + const int32_t personaplex_prompt_frames = + fixture.model->moshi_lm.inference_pre_text_silence_frames + + fixture.model->moshi_lm.inference_post_text_silence_frames; + for (int32_t index = 0; index < personaplex_prompt_frames; ++index) { + bool complete = true; + int32_t remaining = -1; + graph_err = emel::error::cast(moshi::error::graph_runtime); + err = k_no_error; + moshi::event::prefill_personaplex_prompt prefill{}; + prefill.text_token = -1; + prefill.error_out = &err; + prefill.graph_error_out = &graph_err; + prefill.complete_out = &complete; + prefill.remaining_frames_out = &remaining; + + REQUIRE(generator.process_event(prefill)); + CHECK(err == k_no_error); + CHECK(graph_err == k_no_error); + CHECK(complete == (index + 1 == personaplex_prompt_frames)); + CHECK(remaining == personaplex_prompt_frames - index - 1); + CHECK(graph.last_input[0] == fixture.model->moshi_lm.text_padding_id); + CHECK(graph.last_forced_text_token == -1); + } + + err = k_no_error; + graph_err = emel::error::cast(moshi::error::graph_runtime); + REQUIRE(generator.process_event(step)); + CHECK(err == k_no_error); + CHECK(graph_err == k_no_error); + CHECK(graph.call_count == prompt_frames + personaplex_prompt_frames + 1); +} + +TEST_CASE("speech_moshi_generator_step_uses_memory_then_reports_missing_graph_" + "runtime") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::memory::test::recording_kv_actor kv{}; + moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv)}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*fixture.model}; + init.error_out = &err; + REQUIRE(generator.process_event(init)); + + std::array input = {0, 1, 2, 3}; + std::array output = {}; + int32_t text_token = -1; + err = k_no_error; + moshi::event::step step{std::span{input}, + std::span{output}, text_token}; + step.error_out = &err; + + CHECK_FALSE(generator.process_event(step)); + CHECK(err == emel::error::cast(moshi::error::graph_runtime_unavailable)); + CHECK(kv.allocate_slots_count == 1); + CHECK(kv.capture_view_count == 1); +} + +TEST_CASE("speech_moshi_executor_initializes_lm_fixture") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + moshi_executor::sm executor{}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + + REQUIRE(executor.process_event(init)); + CHECK(err == emel::error::cast(moshi_executor::error::none)); +} + +TEST_CASE("speech_moshi_executor_rejects_graph_step_before_initialize") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + moshi_executor::sm executor{}; + std::array input = {0, 1, 2, 3}; + std::array output = {}; + int32_t text_token = -1; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + emel::memory::view::snapshot snapshot{}; + + moshi::event::graph_step step{*fixture.model, snapshot, + std::span{input}, + std::span{output}, text_token}; + step.error_out = &err; + + CHECK_FALSE(executor.process_event(step)); + CHECK(err == emel::error::cast(moshi_executor::error::not_initialized)); +} + +TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { + const auto bytes = + read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + "moshi" / "executor" / "sm.hpp"); + const std::string source{bytes.begin(), bytes.end()}; + const auto action_bytes = + read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + "moshi" / "executor" / "actions.hpp"); + const std::string actions_source{action_bytes.begin(), action_bytes.end()}; + + CHECK(source.find("infer_debug_phase") == std::string::npos); + CHECK(source.find("debug_phase_out != nullptr") == std::string::npos); + CHECK(source.find("effect_store_debug_phase_out") == std::string::npos); + CHECK(source.find("if (ctx.depformer_logits_ok)") == std::string::npos); + CHECK(actions_source.find("if (runtime_ev.ctx.temporal_out_norm_ok)") == + std::string::npos); + CHECK(actions_source.find("add_scaled_embedding") == std::string::npos); + CHECK(actions_source.find("if (!ctx.kernel.process_event(rows_ev))") == + std::string::npos); + CHECK(actions_source.find("if (!ctx.kernel.process_event(projection_ev))") == + std::string::npos); + CHECK(actions_source.find("if (!detail::bind_tensor_view") == + std::string::npos); + CHECK(actions_source.find("(void)detail::bind_tensor_view") == + std::string::npos); + CHECK(actions_source.find("effect_bind_input_text_embedding") != + std::string::npos); + CHECK(actions_source.find("effect_run_embedding_row_fetch") != + std::string::npos); + CHECK(actions_source.find("effect_apply_input_text_embedding_row") != + std::string::npos); + CHECK(actions_source.find("effect_bind_input_audio_embedding") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_text_input_projection") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_audio_input_projection") != + std::string::npos); + CHECK(actions_source.find("effect_run_depformer_input_projection") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_text_input_embedding") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_audio_input_embedding") != + std::string::npos); + CHECK(actions_source.find("effect_bind_temporal_layer_projection") != + std::string::npos); + CHECK(actions_source.find("effect_bind_temporal_layer_out_projection") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_layer_projection") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_layer_out_projection") != + std::string::npos); + CHECK(actions_source.find("effect_bind_temporal_layer_gating_in") != + std::string::npos); + CHECK(actions_source.find("effect_bind_temporal_layer_gating_out") != + std::string::npos); + CHECK(actions_source.find("effect_bind_text_token_logits") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_layer_gating_in") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_layer_gating_out") != + std::string::npos); + CHECK(actions_source.find("effect_bind_depformer_token_logits") != + std::string::npos); + CHECK(actions_source.find("effect_publish_temporal_out_norm") != + std::string::npos); + CHECK(actions_source.find("struct effect_run_temporal_layer_norm {") == + std::string::npos); + CHECK(actions_source.find("struct effect_run_temporal_layer_norm2 {") == + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_layer_norm_rms") != + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_layer_norm_scale") != + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_layer_norm2_rms") != + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_layer_norm2_scale") != + std::string::npos); + CHECK(actions_source.find("struct effect_run_temporal_out_norm {") == + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_out_norm_rms") != + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_out_norm_scale") != + std::string::npos); + CHECK(actions_source.find("effect_apply_temporal_layer_silu_gate") == + std::string::npos); + CHECK(actions_source.find("effect_apply_depformer_layer_silu_gate") == + std::string::npos); + CHECK(actions_source.find("if (!ctx.kernel.process_event(silu_ev))") == + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_layer_silu_gate_silu") != + std::string::npos); + CHECK(actions_source.find("effect_run_temporal_layer_silu_gate_mul") != + std::string::npos); + CHECK(actions_source.find("effect_run_depformer_layer_silu_gate_silu") != + std::string::npos); + CHECK(actions_source.find("effect_run_depformer_layer_silu_gate_mul") != + std::string::npos); + CHECK(actions_source.find("struct effect_run_depformer_layer_norm {") == + std::string::npos); + CHECK(actions_source.find("struct effect_run_depformer_layer_norm2 {") == + std::string::npos); + CHECK(actions_source.find("effect_run_depformer_layer_norm_rms") != + std::string::npos); + CHECK(actions_source.find("effect_run_depformer_layer_norm_scale") != + std::string::npos); + CHECK(actions_source.find("effect_run_depformer_layer_norm2_rms") != + std::string::npos); + CHECK(actions_source.find("effect_run_depformer_layer_norm2_scale") != + std::string::npos); + CHECK(source.find("state_temporal_layer_norm_rms_result_decision") != + std::string::npos); + CHECK(source.find("state_input_text_embedding_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_input_audio_embedding_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_input_projection_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_input_embedding_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_temporal_layer_projection_bind_result_decision") != + std::string::npos); + CHECK( + source.find("state_temporal_layer_out_projection_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_layer_projection_bind_result_decision") != + std::string::npos); + CHECK(source.find( + "state_depformer_layer_out_projection_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_temporal_layer_gating_in_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_temporal_layer_gating_out_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_text_logits_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_layer_gating_in_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_layer_gating_out_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_logits_bind_result_decision") != + std::string::npos); + CHECK(source.find("state_temporal_layer_norm2_rms_result_decision") != + std::string::npos); + CHECK(source.find("state_temporal_out_norm_rms_result_decision") != + std::string::npos); + CHECK(source.find("state_temporal_layer_silu_gate_silu_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_layer_silu_gate_silu_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_layer_norm_rms_result_decision") != + std::string::npos); + CHECK(source.find("state_depformer_layer_norm2_rms_result_decision") != + std::string::npos); + CHECK(source.find("guard_temporal_layer_norm_rms_succeeded") != + std::string::npos); + CHECK(source.find("guard_embedding_view_bound") != std::string::npos); + CHECK(source.find("guard_embedding_row_succeeded") != std::string::npos); + CHECK(source.find("guard_projection_view_bound") != std::string::npos); + CHECK(source.find("guard_depformer_input_projection_bound") != + std::string::npos); + CHECK(source.find("guard_depformer_text_input_projection_succeeded") != + std::string::npos); + CHECK(source.find("guard_depformer_audio_input_projection_succeeded") != + std::string::npos); + CHECK(source.find("guard_temporal_layer_norm2_rms_succeeded") != + std::string::npos); + CHECK(source.find("guard_temporal_out_norm_rms_succeeded") != + std::string::npos); + CHECK(source.find("guard_temporal_layer_silu_gate_silu_succeeded") != + std::string::npos); + CHECK(source.find("guard_depformer_layer_silu_gate_silu_succeeded") != + std::string::npos); + CHECK(source.find("guard_depformer_layer_norm_rms_succeeded") != + std::string::npos); + CHECK(source.find("guard_depformer_layer_norm2_rms_succeeded") != + std::string::npos); +} + +TEST_CASE("speech_moshi_generator_graph_outputs_use_explicit_transitions") { + const auto action_bytes = + read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + "moshi" / "actions.hpp"); + const std::string actions_source{action_bytes.begin(), action_bytes.end()}; + const auto sm_bytes = + read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + "moshi" / "sm.hpp"); + const std::string sm_source{sm_bytes.begin(), sm_bytes.end()}; + + CHECK(actions_source.find( + "if (runtime_ev.request.graph_error_out != nullptr)") == + std::string::npos); + CHECK(actions_source.find("graph_debug_phase_out") == std::string::npos); + CHECK(actions_source.find("effect_store_graph_error_out") != + std::string::npos); + CHECK(actions_source.find("effect_store_graph_debug_phase_out") == + std::string::npos); + CHECK(sm_source.find("state_graph_error_out_decision") != std::string::npos); + CHECK(sm_source.find("state_graph_debug_phase_out_decision") == + std::string::npos); +} + +TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + moshi::action::context generator_ctx{}; + moshi::event::initialize init{*fixture.model}; + moshi::event::initialize_ctx init_ctx{}; + moshi::event::initialize_run init_run{init, init_ctx}; + generator_ctx.lmgen.codebook_count = fixture.model->moshi_lm.n_q + 1; + generator_ctx.lmgen.generated_dep_q = fixture.model->moshi_lm.dep_q; + moshi::action::effect_configure_standard_lmgen{}(init_run, generator_ctx); + CHECK(generator_ctx.lmgen.delayed_dep_q == fixture.model->moshi_lm.dep_q); + + auto generator_snapshot = std::make_unique(); + moshi::event::step_ctx generator_step_ctx{*generator_snapshot}; + std::array generator_input = {}; + std::array generator_output = {}; + int32_t generator_text = -1; + moshi::event::step generator_step{ + std::span{generator_input.data(), 1}, + std::span{generator_output.data(), 1}, generator_text}; + moshi::event::step_run generator_step_run{generator_step, generator_step_ctx}; + moshi::action::effect_mark_memory_error{}( + generator_step_run, generator_ctx); + CHECK(generator_step_ctx.err == emel::error::cast(moshi::error::memory)); + moshi::action::effect_mark_step_request_invalid{}(generator_step_run, + generator_ctx); + CHECK(generator_step_ctx.err == + emel::error::cast(moshi::error::request_shape)); + moshi::action::effect_mark_voice_contract_error{}( + generator_step_run, generator_ctx); + CHECK(generator_step_ctx.err == + emel::error::cast(moshi::error::voice_contract)); + moshi::action::effect_mark_personaplex_prompt_error{}( + generator_step_run, generator_ctx); + CHECK(generator_step_ctx.err == + emel::error::cast(moshi::error::personaplex_prompt)); + CHECK( + moshi::guard::guard_memory_rejected{}(generator_step_run, generator_ctx)); + + moshi::event::begin_personaplex_prompt begin_prompt{}; + moshi::event::begin_personaplex_prompt_ctx begin_prompt_ctx{}; + moshi::event::begin_personaplex_prompt_run begin_prompt_run{begin_prompt, + begin_prompt_ctx}; + CHECK(moshi::guard::guard_personaplex_prompt_begin_invalid{}(begin_prompt_run, + generator_ctx)); + + auto prompt_snapshot = std::make_unique(); + moshi::event::prefill_personaplex_prompt prompt_prefill{}; + moshi::event::prefill_personaplex_prompt_ctx prompt_prefill_ctx{ + *prompt_snapshot}; + moshi::event::prefill_personaplex_prompt_run prompt_prefill_run{ + prompt_prefill, prompt_prefill_ctx}; + CHECK(moshi::guard::guard_personaplex_prompt_prefill_request_invalid{}( + prompt_prefill_run, generator_ctx)); + CHECK(moshi::guard::guard_personaplex_prompt_phase_invalid{}( + prompt_prefill_run, generator_ctx)); + CHECK(moshi::guard::guard_no_personaplex_prompt_complete_out{}( + prompt_prefill_run, generator_ctx)); + CHECK(moshi::guard::guard_no_personaplex_prompt_remaining_out{}( + prompt_prefill_run, generator_ctx)); + + generator_ctx.session.model = fixture.model.get(); + generator_ctx.session.text_card = fixture.model->moshi_lm.text_card; + generator_ctx.voice.loaded = true; + generator_ctx.voice.ready = true; + generator_ctx.voice.prompt_started = true; + generator_ctx.voice.prompt_ready = false; + generator_ctx.voice.text_tokens_remaining = 1; + prompt_prefill.text_token = fixture.model->moshi_lm.text_card; + CHECK(moshi::guard::guard_personaplex_prompt_phase_invalid{}( + prompt_prefill_run, generator_ctx)); + + moshi_callback_probe callback_probe{}; + init.on_done = + emel::callback::from< + moshi_callback_probe, + &moshi_callback_probe::on_generator_initialize_done>(&callback_probe); + init.on_error = + emel::callback::from< + moshi_callback_probe, + &moshi_callback_probe::on_generator_initialize_error>( + &callback_probe); + generator_ctx.session.n_q = fixture.model->moshi_lm.n_q; + generator_ctx.session.dep_q = fixture.model->moshi_lm.dep_q; + init_ctx.err = emel::error::cast(moshi::error::bind_failed); + moshi::action::effect_emit_initialize_done{}(init_run, generator_ctx); + CHECK(callback_probe.n_q == fixture.model->moshi_lm.n_q); + CHECK(callback_probe.dep_q == fixture.model->moshi_lm.dep_q); + CHECK(callback_probe.request == &init); + moshi::action::effect_emit_initialize_error{}(init_run, generator_ctx); + CHECK(callback_probe.err == emel::error::cast(moshi::error::bind_failed)); + + moshi::event::load_voice load_voice{*fixture.model}; + moshi::event::load_voice_ctx load_voice_ctx{}; + moshi::event::load_voice_run load_voice_run{load_voice, load_voice_ctx}; + load_voice.on_done = + emel::callback::from< + moshi_callback_probe, + &moshi_callback_probe::on_generator_load_voice_done>(&callback_probe); + load_voice.on_error = + emel::callback::from< + moshi_callback_probe, + &moshi_callback_probe::on_generator_load_voice_error>( + &callback_probe); + generator_ctx.voice.prompt_frame_count = 7; + load_voice_ctx.err = emel::error::cast(moshi::error::voice_contract); + moshi::action::effect_emit_load_voice_done{}(load_voice_run, generator_ctx); + CHECK(callback_probe.prompt_frames == 7); + CHECK(callback_probe.request == &load_voice); + moshi::action::effect_emit_load_voice_error{}(load_voice_run, generator_ctx); + CHECK(callback_probe.err == emel::error::cast(moshi::error::voice_contract)); + + moshi::event::prefill_voice prefill_voice{}; + emel::error::type generator_graph_err = k_no_error; + bool voice_complete = false; + int32_t voice_remaining = -1; + prefill_voice.graph_error_out = &generator_graph_err; + prefill_voice.complete_out = &voice_complete; + prefill_voice.remaining_frames_out = &voice_remaining; + prefill_voice.on_done = + emel::callback::from< + moshi_callback_probe, + &moshi_callback_probe::on_generator_prefill_voice_done>( + &callback_probe); + prefill_voice.on_error = + emel::callback::from< + moshi_callback_probe, + &moshi_callback_probe::on_generator_prefill_voice_error>( + &callback_probe); + moshi::event::prefill_voice_ctx prefill_voice_ctx{*generator_snapshot}; + prefill_voice_ctx.graph_error = + emel::error::cast(moshi::error::graph_runtime); + prefill_voice_ctx.complete = true; + prefill_voice_ctx.remaining_frames = 3; + prefill_voice_ctx.err = + emel::error::cast(moshi::error::graph_runtime_unavailable); + moshi::event::prefill_voice_run prefill_voice_run{prefill_voice, + prefill_voice_ctx}; + moshi::action::effect_store_graph_error_out{}(prefill_voice_run, + generator_ctx); + moshi::action::effect_store_voice_complete_out{}(prefill_voice_run, + generator_ctx); + moshi::action::effect_store_voice_remaining_out{}(prefill_voice_run, + generator_ctx); + CHECK(generator_graph_err == emel::error::cast(moshi::error::graph_runtime)); + CHECK(voice_complete); + CHECK(voice_remaining == 3); + moshi::action::effect_emit_prefill_voice_done{}(prefill_voice_run, + generator_ctx); + CHECK(callback_probe.complete); + CHECK(callback_probe.remaining_frames == 3); + CHECK(callback_probe.request == &prefill_voice); + moshi::action::effect_emit_prefill_voice_error{}(prefill_voice_run, + generator_ctx); + CHECK(callback_probe.err == + emel::error::cast(moshi::error::graph_runtime_unavailable)); + + begin_prompt.on_done = emel::callback::from( + &callback_probe); + begin_prompt.on_error = emel::callback::from( + &callback_probe); + begin_prompt_ctx.remaining_frames = 5; + begin_prompt_ctx.err = emel::error::cast(moshi::error::personaplex_prompt); + moshi::action::effect_emit_begin_personaplex_prompt_done{}(begin_prompt_run, + generator_ctx); + CHECK(callback_probe.remaining_frames == 5); + CHECK(callback_probe.request == &begin_prompt); + moshi::action::effect_emit_begin_personaplex_prompt_error{}(begin_prompt_run, + generator_ctx); + CHECK(callback_probe.err == + emel::error::cast(moshi::error::personaplex_prompt)); + + bool prompt_complete = false; + int32_t prompt_remaining = -1; + prompt_prefill.complete_out = &prompt_complete; + prompt_prefill.remaining_frames_out = &prompt_remaining; + prompt_prefill.on_done = emel::callback::from( + &callback_probe); + prompt_prefill.on_error = emel::callback::from( + &callback_probe); + prompt_prefill_ctx.complete = true; + prompt_prefill_ctx.remaining_frames = 2; + prompt_prefill_ctx.err = + emel::error::cast(moshi::error::graph_runtime_unavailable); + moshi::action::effect_store_personaplex_prompt_complete_out{}( + prompt_prefill_run, generator_ctx); + moshi::action::effect_store_personaplex_prompt_remaining_out{}( + prompt_prefill_run, generator_ctx); + CHECK(prompt_complete); + CHECK(prompt_remaining == 2); + moshi::action::effect_emit_prefill_personaplex_prompt_done{}( + prompt_prefill_run, generator_ctx); + CHECK(callback_probe.complete); + CHECK(callback_probe.remaining_frames == 2); + CHECK(callback_probe.request == &prompt_prefill); + moshi::action::effect_emit_prefill_personaplex_prompt_error{}( + prompt_prefill_run, generator_ctx); + CHECK(callback_probe.err == + emel::error::cast(moshi::error::graph_runtime_unavailable)); + + bool produced = false; + emel::error::type generator_err = k_no_error; + generator_step.produced_out = &produced; + generator_step.error_out = &generator_err; + generator_step.on_done = + emel::callback::from< + moshi_callback_probe, &moshi_callback_probe::on_generator_step_done>( + &callback_probe); + generator_step.on_error = + emel::callback::from< + moshi_callback_probe, &moshi_callback_probe::on_generator_step_error>( + &callback_probe); + generator_step_ctx.produced = true; + generator_step_ctx.err = emel::error::cast(moshi::error::request_shape); + moshi::action::effect_store_produced_out{}(generator_step_run, generator_ctx); + moshi::action::effect_store_error_out{}( + generator_step_run, generator_ctx); + CHECK(produced); + CHECK(generator_err == emel::error::cast(moshi::error::request_shape)); + moshi::action::effect_emit_step_done{}(generator_step_run, generator_ctx); + CHECK(callback_probe.produced); + CHECK(callback_probe.request == &generator_step); + moshi::action::effect_emit_step_error{}(generator_step_run, generator_ctx); + CHECK(callback_probe.err == emel::error::cast(moshi::error::request_shape)); + moshi::action::effect_mark_unexpected_and_store{}(generator_step_run, + generator_ctx); + CHECK(generator_step_ctx.err == + emel::error::cast(moshi::error::unexpected_event)); + CHECK(generator_err == emel::error::cast(moshi::error::unexpected_event)); + + const auto &lm = fixture.model->moshi_lm; + emel::memory::view::snapshot snapshot{}; + snapshot.max_sequences = 4; + snapshot.sequence_active[0] = 1; + snapshot.sequence_length_values[0] = 1; + snapshot.sequence_kv_block_count[0] = 1; + snapshot.sequence_kv_blocks[0][0] = 0; + + std::array input = {}; + std::array output = {}; + std::array embedding = {}; + input.fill(moshi_executor::detail::k_token_zero); + input[0] = lm.text_padding_id; + input[1] = 0; + int32_t text_token = -1; + moshi::event::graph_step step{ + *fixture.model, snapshot, + std::span{input.data(), static_cast(lm.n_q + 1)}, + std::span{output.data(), static_cast(lm.dep_q)}, + text_token}; + step.input_embedding = + std::span{embedding.data(), static_cast(lm.dim)}; + moshi_executor::event::step_ctx step_ctx{}; + moshi_executor::event::step_run step_run{step, step_ctx}; + moshi_executor::action::context executor_ctx{}; + executor_ctx.session.model = fixture.model.get(); + executor_ctx.session.codebook_count = lm.n_q + 1; + executor_ctx.session.dep_q = lm.dep_q; + executor_ctx.session.text_card = lm.text_card; + executor_ctx.session.audio_card = lm.card; + executor_ctx.session.hidden_dim = lm.dim; + + moshi_executor::event::initialize executor_init{*fixture.model}; + moshi_executor::event::initialize_ctx executor_init_ctx{}; + moshi_executor::event::initialize_run executor_init_run{executor_init, + executor_init_ctx}; + executor_init.on_done = + emel::callback:: + from( + &callback_probe); + executor_init.on_error = + emel::callback:: + from( + &callback_probe); + executor_init_ctx.err = emel::error::cast(moshi_executor::error::bind_failed); + moshi_executor::action::effect_emit_initialize_done{}(executor_init_run, + executor_ctx); + CHECK(callback_probe.n_q == lm.n_q); + CHECK(callback_probe.dep_q == lm.dep_q); + CHECK(callback_probe.request == &executor_init); + moshi_executor::action::effect_emit_initialize_error{}(executor_init_run, + executor_ctx); + CHECK(callback_probe.err == + emel::error::cast(moshi_executor::error::bind_failed)); + executor_init_ctx.err = k_no_error; + moshi_executor::action::effect_mark_bind_failed{}(executor_init_run, + executor_ctx); + CHECK(executor_init_ctx.err == + emel::error::cast(moshi_executor::error::bind_failed)); + + emel::error::type executor_step_err = k_no_error; + step.error_out = &executor_step_err; + moshi_executor::action::effect_mark_model_mismatch{}(step_run, executor_ctx); + CHECK(step_ctx.err == + emel::error::cast(moshi_executor::error::model_mismatch)); + moshi_executor::action::effect_mark_request_shape{}(step_run, executor_ctx); + CHECK(step_ctx.err == + emel::error::cast(moshi_executor::error::request_shape)); + moshi_executor::action::effect_store_error_out< + moshi_executor::event::step_run>{}(step_run, executor_ctx); + CHECK(executor_step_err == + emel::error::cast(moshi_executor::error::request_shape)); + moshi_executor::action::effect_mark_unexpected_and_store{}(step_run, + executor_ctx); + CHECK(step_ctx.err == + emel::error::cast(moshi_executor::error::unexpected_event)); + CHECK(executor_step_err == + emel::error::cast(moshi_executor::error::unexpected_event)); + + CHECK(moshi_executor::guard::guard_step_model_matches{}(step_run, + executor_ctx)); + executor_ctx.session.model = nullptr; + CHECK(moshi_executor::guard::guard_step_model_mismatch{}(step_run, + executor_ctx)); + executor_ctx.session.model = fixture.model.get(); + CHECK( + moshi_executor::guard::guard_step_shape_valid{}(step_run, executor_ctx)); + executor_ctx.session.codebook_count += 1; + CHECK(moshi_executor::guard::guard_step_shape_invalid{}(step_run, + executor_ctx)); + executor_ctx.session.codebook_count = lm.n_q + 1; + + CHECK(moshi_executor::guard::guard_external_input_embedding_supported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_input_embedding_supported{}(step_run, + executor_ctx)); + step.input_embedding = {}; + CHECK_FALSE(moshi_executor::guard::guard_input_embedding_unsupported{}( + step_run, executor_ctx)); + CHECK_FALSE(moshi_executor::guard::guard_token_input_embedding_unsupported{}( + step_run, executor_ctx)); + step.input_embedding = + std::span{embedding.data(), static_cast(lm.dim)}; + + CHECK_FALSE(moshi_executor::guard::guard_input_text_embedding_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_input_text_embedding_failed{}( + step_run, executor_ctx)); + step_ctx.input_text_embedding_ok = true; + CHECK(moshi_executor::guard::guard_input_text_embedding_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_embedding_view_bind_failed{}( + step_run, executor_ctx)); + step_ctx.embedding_view_bound = true; + CHECK(moshi_executor::guard::guard_embedding_view_bound{}(step_run, + executor_ctx)); + CHECK(moshi_executor::guard::guard_embedding_row_failed{}(step_run, + executor_ctx)); + step_ctx.embedding_row_ok = true; + CHECK(moshi_executor::guard::guard_embedding_row_succeeded{}(step_run, + executor_ctx)); + CHECK(moshi_executor::guard::guard_projection_view_bind_failed{}( + step_run, executor_ctx)); + step_ctx.projection_view_bound = true; + CHECK(moshi_executor::guard::guard_projection_view_bound{}(step_run, + executor_ctx)); + + step_ctx.input_audio_codebook_index = 0; + CHECK(moshi_executor::guard::guard_current_input_audio_token_present{}( + step_run, executor_ctx)); + input[1] = moshi_executor::detail::k_token_zero; + CHECK(moshi_executor::guard::guard_current_input_audio_token_zero{}( + step_run, executor_ctx)); + step.input_embedding = {}; + CHECK_FALSE( + moshi_executor::guard::guard_current_input_audio_token_unsupported{}( + step_run, executor_ctx)); + step.input_embedding = + std::span{embedding.data(), static_cast(lm.dim)}; + + CHECK(moshi_executor::guard::guard_input_audio_embedding_failed{}( + step_run, executor_ctx)); + step_ctx.input_audio_embedding_ok = true; + CHECK(moshi_executor::guard::guard_input_audio_embedding_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_more_input_audio_codebooks{}( + step_run, executor_ctx)); + step_ctx.input_audio_codebook_index = lm.n_q - 1; + CHECK(moshi_executor::guard::guard_input_audio_codebooks_complete{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_input_embedding_failed{}(step_run, + executor_ctx)); + step_ctx.input_embedding_ok = true; + CHECK(moshi_executor::guard::guard_input_embedding_succeeded{}(step_run, + executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_kv_binding_missing{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_kv_bind_failed{}(step_run, + executor_ctx)); + + std::array key_cache = {}; + std::array value_cache = {}; + std::array offsets = {0}; + step_ctx.temporal_kv.key_cache = std::span{key_cache}; + step_ctx.temporal_kv.value_cache = std::span{value_cache}; + step_ctx.temporal_kv.layer_cache_offsets = std::span{offsets}; + step_ctx.temporal_kv.layer_count = 1; + step_ctx.temporal_kv.position_capacity = 1; + step_ctx.temporal_kv.block_tokens = 1; + step_ctx.temporal_kv.kv_dim = lm.dim; + step_ctx.temporal_kv_bound = true; + CHECK( + moshi_executor::guard::guard_temporal_kv_bound{}(step_run, executor_ctx)); + + CHECK_FALSE(moshi_executor::guard::guard_temporal_layer_norm_unsupported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_norm_rms_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_norm_rms_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_norm_rms_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_norm_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_norm_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_norm_succeeded{}( + step_run, executor_ctx)); + CHECK_FALSE( + moshi_executor::guard::guard_temporal_layer_projection_unsupported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_projection_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_projection_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_projection_succeeded{}( + step_run, executor_ctx)); + CHECK_FALSE(moshi_executor::guard::guard_temporal_layer_rope_unsupported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_rope_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_rope_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_rope_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_cache_write_unsupported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_cache_write_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_cache_write_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_cache_write_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_attention_unsupported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_attention_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_attention_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_attention_succeeded{}( + step_run, executor_ctx)); + CHECK_FALSE( + moshi_executor::guard::guard_temporal_layer_out_projection_unsupported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_out_projection_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_out_projection_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_out_projection_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_residual_failed{}( + step_run, executor_ctx)); + step_ctx.temporal_layer_residual_ok = true; + CHECK(moshi_executor::guard::guard_temporal_layer_residual_succeeded{}( + step_run, executor_ctx)); +} + +TEST_CASE("speech_moshi_executor_embeds_input_before_unsupported_transformer") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + moshi_executor::sm executor{}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + REQUIRE(executor.process_event(init)); + + std::array input = {}; + std::array output = {}; + input.fill(-1); + input[0] = fixture.model->moshi_lm.text_padding_id; + int32_t text_token = -1; + emel::memory::view::snapshot snapshot{}; + err = emel::error::cast(moshi_executor::error::none); + + moshi::event::graph_step step{ + *fixture.model, snapshot, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + step.error_out = &err; + + CHECK_FALSE(executor.process_event(step)); + CHECK(err == + emel::error::cast(moshi_executor::error::graph_execution_unsupported)); + CHECK(text_token == -1); +} + +TEST_CASE( + "speech_moshi_executor_writes_temporal_kv_and_text_before_depformer") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + temporal_kv_probe probe{}; + moshi_executor::sm executor{ + moshi_executor::bind_temporal_kv_cache(&probe, temporal_kv_probe_bind)}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + REQUIRE(executor.process_event(init)); + + std::array input = {}; + std::array output = {}; + input.fill(-1); + input[0] = fixture.model->moshi_lm.text_padding_id; + int32_t text_token = -1; + emel::memory::view::snapshot snapshot{}; + snapshot.max_sequences = 8; + snapshot.sequence_active[7] = 1; + snapshot.sequence_length_values[7] = 3; + snapshot.sequence_kv_block_count[7] = 1; + snapshot.sequence_kv_blocks[7][0] = 0; + err = emel::error::cast(moshi_executor::error::none); + + moshi::event::graph_step step{ + *fixture.model, snapshot, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + step.sequence_id = 7; + step.error_out = &err; + + CHECK_FALSE(executor.process_event(step)); + CHECK(err == + emel::error::cast(moshi_executor::error::graph_execution_unsupported)); + CHECK(probe.call_count == 1); + CHECK(probe.sequence_id == 7); + CHECK(probe.sequence_length == 3); + const size_t write_offset = + static_cast(snapshot.sequence_length_values[7] - 1) * + static_cast(fixture.model->moshi_lm.dim); + const size_t write_end = + write_offset + static_cast(fixture.model->moshi_lm.dim); + REQUIRE(write_end <= probe.key_cache.size()); + CHECK(std::any_of( + probe.key_cache.begin() + static_cast(write_offset), + probe.key_cache.begin() + static_cast(write_end), + [](const uint16_t value) { return value != 0u; })); + CHECK(std::any_of( + probe.value_cache.begin() + static_cast(write_offset), + probe.value_cache.begin() + static_cast(write_end), + [](const uint16_t value) { return value != 0u; })); + const int32_t last_layer = fixture.model->moshi_lm.num_layers - 1; + REQUIRE(last_layer >= 0); + const size_t last_layer_write_offset = + probe.layer_offsets[static_cast(last_layer)] + write_offset; + const size_t last_layer_write_end = + last_layer_write_offset + + static_cast(fixture.model->moshi_lm.dim); + REQUIRE(last_layer_write_end <= probe.key_cache.size()); + CHECK(std::any_of(probe.key_cache.begin() + + static_cast(last_layer_write_offset), + probe.key_cache.begin() + + static_cast(last_layer_write_end), + [](const uint16_t value) { return value != 0u; })); + CHECK(std::any_of(probe.value_cache.begin() + + static_cast(last_layer_write_offset), + probe.value_cache.begin() + + static_cast(last_layer_write_end), + [](const uint16_t value) { return value != 0u; })); + CHECK(text_token >= 0); + CHECK(text_token < fixture.model->moshi_lm.text_card); +} + +TEST_CASE("speech_moshi_executor_accepts_personaplex_voice_embedding_step") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + temporal_kv_probe temporal_probe{}; + depformer_kv_probe depformer_probe{}; + const auto temporal_kv = moshi_executor::bind_temporal_kv_cache( + &temporal_probe, temporal_kv_probe_bind); + const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( + &depformer_probe, depformer_kv_probe_bind); + moshi_executor::sm executor{ + moshi_executor::bind_kv_caches(temporal_kv, depformer_kv)}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + REQUIRE(executor.process_event(init)); + + std::array embedding = {}; + for (int32_t index = 0; index < fixture.model->moshi_lm.dim; ++index) { + embedding[static_cast(index)] = + 0.001f * static_cast(index + 1); + } + std::array input = {}; + std::array output = {}; + input.fill(-1); + input[0] = fixture.model->moshi_lm.text_padding_id; + int32_t text_token = -1; + emel::memory::view::snapshot snapshot{}; + snapshot.max_sequences = 8; + snapshot.sequence_active[3] = 1; + snapshot.sequence_length_values[3] = 1; + snapshot.sequence_kv_block_count[3] = 1; + snapshot.sequence_kv_blocks[3][0] = 0; + + moshi::event::graph_step step{ + *fixture.model, snapshot, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + step.sequence_id = 3; + step.input_embedding = std::span{ + embedding.data(), static_cast(fixture.model->moshi_lm.dim)}; + step.forced_text_token = fixture.model->moshi_lm.text_padding_id; + step.error_out = &err; + + REQUIRE(executor.process_event(step)); + CHECK(err == emel::error::cast(moshi_executor::error::none)); + CHECK(text_token == fixture.model->moshi_lm.text_padding_id); + CHECK(temporal_probe.call_count == 1); + CHECK(depformer_probe.call_count == 1); + for (int32_t index = 0; index < fixture.model->moshi_lm.dep_q; ++index) { + CHECK(output[static_cast(index)] >= 0); + CHECK(output[static_cast(index)] < fixture.model->moshi_lm.card); + } +} + +TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + temporal_kv_probe temporal_probe{}; + depformer_kv_probe depformer_probe{}; + const auto temporal_kv = moshi_executor::bind_temporal_kv_cache( + &temporal_probe, temporal_kv_probe_bind); + const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( + &depformer_probe, depformer_kv_probe_bind); + moshi_executor::sm executor{ + moshi_executor::bind_kv_caches(temporal_kv, depformer_kv)}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + REQUIRE(executor.process_event(init)); + + std::array input = {}; + std::array output = {}; + input.fill(-1); + input[0] = fixture.model->moshi_lm.text_padding_id; + int32_t text_token = -1; + emel::memory::view::snapshot snapshot{}; + snapshot.max_sequences = 8; + snapshot.sequence_active[7] = 1; + snapshot.sequence_length_values[7] = 3; + snapshot.sequence_kv_block_count[7] = 1; + snapshot.sequence_kv_blocks[7][0] = 0; + err = emel::error::cast(moshi_executor::error::none); + depformer_probe.offset = 37; + + moshi::event::graph_step step{ + *fixture.model, snapshot, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + step.sequence_id = 7; + step.error_out = &err; + + CHECK(executor.process_event(step)); + CHECK(err == emel::error::cast(moshi_executor::error::none)); + CHECK(temporal_probe.call_count == 1); + CHECK(depformer_probe.call_count == 1); + CHECK(depformer_probe.offset == fixture.model->moshi_lm.dep_q); + CHECK(text_token >= 0); + CHECK(text_token < fixture.model->moshi_lm.text_card); + for (int32_t index = 0; index < fixture.model->moshi_lm.dep_q; ++index) { + CHECK(output[static_cast(index)] >= 0); + CHECK(output[static_cast(index)] < fixture.model->moshi_lm.card); + } + const int32_t last_layer = fixture.model->moshi_lm.depformer_num_layers - 1; + REQUIRE(last_layer >= 0); + const size_t last_layer_offset = + depformer_probe.layer_offsets[static_cast(last_layer)]; + const size_t last_layer_end = + last_layer_offset + + static_cast(fixture.model->moshi_lm.depformer_context) * + static_cast(fixture.model->moshi_lm.depformer_dim); + REQUIRE(last_layer_end <= depformer_probe.key_cache.size()); + CHECK(std::any_of(depformer_probe.key_cache.begin() + + static_cast(last_layer_offset), + depformer_probe.key_cache.begin() + + static_cast(last_layer_end), + [](const uint16_t value) { return value != 0u; })); + CHECK(std::any_of(depformer_probe.value_cache.begin() + + static_cast(last_layer_offset), + depformer_probe.value_cache.begin() + + static_cast(last_layer_end), + [](const uint16_t value) { return value != 0u; })); +} + +TEST_CASE("speech_moshi_e2e_encodes_audio_generates_tokens_and_decodes_audio") { + auto codec_fixture = load_fixture_or_skip("mimi-tiny.gguf"); + auto lm_fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (codec_fixture.model == nullptr || lm_fixture.model == nullptr) { + return; + } + + std::vector prepared( + mimi::prepared_arena_floats(*codec_fixture.model)); + std::vector state(mimi::state_arena_floats(*codec_fixture.model)); + std::vector workspace( + mimi::workspace_arena_floats(*codec_fixture.model)); + std::vector frame(mimi::frame_arena_floats(*codec_fixture.model)); + mimi::sm codec{}; + emel::error::type codec_err = emel::error::cast(mimi::error::none); + g_mimi_frame_samples = 0; + g_mimi_n_q = 0; + mimi::event::initialize codec_init{ + *codec_fixture.model, std::span{prepared}, std::span{state}, + std::span{workspace}, std::span{frame}}; + codec_init.error_out = &codec_err; + codec_init.on_done = emel::callback::from<&on_mimi_initialized>(); + REQUIRE(codec.process_event(codec_init)); + REQUIRE(codec_err == emel::error::cast(mimi::error::none)); + REQUIRE(g_mimi_frame_samples > 0); + REQUIRE(codec_fixture.model->mimi.card == lm_fixture.model->moshi_lm.card); + const int32_t public_n_q = lm_fixture.model->moshi_lm.inference_dep_q; + REQUIRE(public_n_q > 0); + REQUIRE(public_n_q <= lm_fixture.model->moshi_lm.n_q); + REQUIRE(g_mimi_n_q == public_n_q); + const int32_t needed_tokens = + (lm_fixture.model->moshi_lm.n_q + 1) - public_n_q - 1; + REQUIRE(needed_tokens > 0); + + const auto pcm = deterministic_pcm(g_mimi_frame_samples); + std::vector encoded_codes(static_cast(g_mimi_n_q), -1); + mimi::event::encode_frame encode{std::span{pcm}, + std::span{encoded_codes}}; + encode.error_out = &codec_err; + REQUIRE(codec.process_event(encode)); + REQUIRE(codec_err == emel::error::cast(mimi::error::none)); + for (const int32_t code : encoded_codes) { + REQUIRE(code >= 0); + REQUIRE(code < lm_fixture.model->moshi_lm.card); + } + + temporal_kv_probe temporal_probe{}; + depformer_kv_probe depformer_probe{}; + const auto temporal_kv = moshi_executor::bind_temporal_kv_cache( + &temporal_probe, temporal_kv_probe_bind); + const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( + &depformer_probe, depformer_kv_probe_bind); + moshi_executor::sm executor{ + moshi_executor::bind_kv_caches(temporal_kv, depformer_kv)}; + emel::error::type executor_err = + emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize executor_init{*lm_fixture.model}; + executor_init.error_out = &executor_err; + REQUIRE(executor.process_event(executor_init)); + REQUIRE(executor_err == emel::error::cast(moshi_executor::error::none)); + + moshi::sm generator{emel::memory::hybrid::kv_binding{}, + moshi_executor::bind_graph_executor(executor)}; + emel::error::type generator_err = k_no_error; + moshi::event::initialize generator_init{*lm_fixture.model}; + generator_init.error_out = &generator_err; + generator_init.max_blocks = 16; + generator_init.block_tokens = 4; + REQUIRE(generator.process_event(generator_init)); + REQUIRE(generator_err == k_no_error); + + std::array generated_codes = {}; + generated_codes.fill(-1); + std::array tail_input = {}; + tail_input.fill(-1); + REQUIRE(needed_tokens == public_n_q); + for (int32_t index = 0; index < needed_tokens; ++index) { + tail_input[static_cast(index)] = + encoded_codes[static_cast(index)]; + } + int32_t text_token = -1; + bool produced = false; + emel::error::type graph_err = emel::error::cast(moshi::error::none); + + moshi::event::step seed_step{ + std::span{tail_input.data(), + static_cast(needed_tokens)}, + std::span{generated_codes.data(), + static_cast(public_n_q)}, + text_token}; + seed_step.error_out = &generator_err; + seed_step.graph_error_out = &graph_err; + seed_step.produced_out = &produced; + REQUIRE(generator.process_event(seed_step)); + REQUIRE(generator_err == k_no_error); + REQUIRE(graph_err == k_no_error); + CHECK_FALSE(produced); + + int32_t generation_attempts = 0; + for (int32_t attempt = 0; attempt < 5; ++attempt) { + generated_codes.fill(-1); + text_token = -1; + produced = false; + graph_err = emel::error::cast(moshi::error::none); + moshi::event::step generate_step{ + std::span{tail_input.data(), + static_cast(needed_tokens)}, + std::span{generated_codes.data(), + static_cast(public_n_q)}, + text_token}; + generate_step.error_out = &generator_err; + generate_step.graph_error_out = &graph_err; + generate_step.produced_out = &produced; + CAPTURE(attempt); + CAPTURE(generator_err); + CAPTURE(graph_err); + REQUIRE(generator.process_event(generate_step)); + REQUIRE(generator_err == k_no_error); + REQUIRE(graph_err == k_no_error); + ++generation_attempts; + if (produced && generation_attempts >= 2) { + break; + } + } + + REQUIRE(produced); + REQUIRE(generation_attempts >= 2); + REQUIRE(temporal_probe.call_count >= 3); + REQUIRE(depformer_probe.call_count >= 3); + REQUIRE(text_token >= 0); + REQUIRE(text_token < lm_fixture.model->moshi_lm.text_card); + for (int32_t index = 0; index < public_n_q; ++index) { + const int32_t code = generated_codes[static_cast(index)]; + REQUIRE(code >= 0); + REQUIRE(code < codec_fixture.model->mimi.card); + } + + std::vector decoded(static_cast(g_mimi_frame_samples), 0.0f); + mimi::event::decode_frame decode{ + std::span{generated_codes.data(), + static_cast(public_n_q)}, + std::span{decoded}}; + decode.error_out = &codec_err; + REQUIRE(codec.process_event(decode)); + REQUIRE(codec_err == emel::error::cast(mimi::error::none)); + + bool all_finite = true; + bool has_energy = false; + for (const float sample : decoded) { + all_finite = all_finite && std::isfinite(sample); + has_energy = has_energy || std::abs(sample) > 1.0e-8f; + } + CHECK(all_finite); + CHECK(has_energy); +} + +TEST_CASE( + "speech_moshi_generator_uses_emel_executor_binding_without_fake_tokens") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::memory::test::recording_kv_actor kv{}; + moshi_executor::sm executor{}; + emel::error::type executor_err = + emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize executor_init{*fixture.model}; + executor_init.error_out = &executor_err; + REQUIRE(executor.process_event(executor_init)); + + moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv), + moshi_executor::bind_graph_executor(executor)}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*fixture.model}; + init.error_out = &err; + REQUIRE(generator.process_event(init)); + + std::array input = {0, 1, 2, 3}; + std::array output = {}; + output.fill(-1); + int32_t text_token = -1; + moshi::event::step step{std::span{input}, + std::span{output}, text_token}; + step.error_out = &err; + + CHECK_FALSE(generator.process_event(step)); + CHECK(err == emel::error::cast(moshi::error::graph_runtime)); + CHECK(kv.allocate_slots_count == 1); + CHECK(kv.capture_view_count == 1); + CHECK(text_token == -1); + CHECK(output[0] == -1); +} + +TEST_CASE("speech_moshi_generator_runs_injected_graph_through_delay_cache") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::memory::test::recording_kv_actor kv{}; + recording_graph_executor graph{}; + auto graph_binding = + moshi::action::bind_graph_executor(&graph, dispatch_recording_graph); + moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv), graph_binding}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*fixture.model}; + init.error_out = &err; + REQUIRE(generator.process_event(init)); + + std::array input = {0, 1, 2, 3}; + std::array output = {}; + output.fill(-1); + const size_t public_n_q = + static_cast(fixture.model->moshi_lm.inference_dep_q); + REQUIRE(public_n_q < output.size()); + int32_t text_token = -1; + bool produced = true; + emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); + + moshi::event::step first{std::span{input}, + std::span{output.data(), public_n_q}, + text_token}; + first.error_out = &err; + first.produced_out = &produced; + first.graph_error_out = &graph_err; + REQUIRE(generator.process_event(first)); + CHECK(err == k_no_error); + CHECK(graph_err == k_no_error); + CHECK_FALSE(produced); + CHECK(graph.call_count == 1); + CHECK(kv.allocate_slots_count == 1); + CHECK(kv.capture_view_count == 1); + CHECK(graph.first_sequence_length == 1); + CHECK(graph.first_input[0] == fixture.model->moshi_lm.text_card); + CHECK(graph.first_input[1] == fixture.model->moshi_lm.card); + + produced = false; + graph_err = emel::error::cast(moshi::error::graph_runtime); + moshi::event::step second{std::span{input}, + std::span{output.data(), public_n_q}, + text_token}; + second.error_out = &err; + second.produced_out = &produced; + second.graph_error_out = &graph_err; + REQUIRE(generator.process_event(second)); + CHECK(err == k_no_error); + CHECK(graph_err == k_no_error); + CHECK(produced); + CHECK(graph.call_count == 2); + CHECK(text_token == 101); + CHECK(output[0] == 1010); + CHECK(output[public_n_q] == -1); + CHECK(kv.allocate_slots_count == 2); + CHECK(kv.capture_view_count == 2); + CHECK(graph.second_sequence_length == 2); +} diff --git a/tools/bench/__pycache__/moshi_gguf_convert.cpython-314.pyc b/tools/bench/__pycache__/moshi_gguf_convert.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..087136e78db7418ce69d14fd9e2f4ca1a7b28bd5 GIT binary patch literal 100099 zcmd4433MCRnJ!q^cW~b~a3{n~q)3WdNQsiDU6cgLpcjcWM1mA7ZYqGX1lutjJ24f< zEx6;f;Evsf&vQ=bo@7E#CljVS^IF|AeI~P_@AlvS{`dd?``>1}&CKC?@*hq<_g$-s`zLykuUs*pdhk;n z$Avf-7vM%Xm+FY>usWcwqOkgiCZJ)z+JKh*>H<3Us}JbeuOVPyzs7)({h9(M{A!Mv z4_g8j219$qde|1QRdFs|z&@f0WQ{li*(2IO&WJ9MJE9NdjTi#?BgR0%h$&Dw!Uc*( zRDt3Vb)W=sOYyx7-^=m6V#FM%9I*tdMyvtHh%Hb(Vh_}eWCdzRwgl<`vwox|(BRSs z8b`u`Cd7BT41q1Kw*t+sKMk~u>l=YiS7BhA>+L|7>zjdYSCOmORpKgjmAT4Y6$n?ls@ipd z9+xAq{k)}`b5*-)wyVT;E#UB6Tg18Qy42#EE~(`My&2=yBW}ZnxH}k}Mtp0MzXf)> zoOs?+#7$)fcDb4nZeiiwu2zKGSh&yCj__6%?ss({+{wawT-y-tV&T26ZiIVSc)+zC z;a(Qr=h}hrP8Qzp+J*3L7CzwWL%5%X2VHv*-pj%VT>}X3W8p)t{Rkgm;lr*$gb%Xt z5!WGv53}%5*Aaw|vhXq2F@%q^@Nw4(gojx8gzL{-C-HQOo~BfRA=ha!m~ zGk8ABo=>};K-kT~F4r)^PqOeC*HZ{T&BA9{J3fQwbBT6*!gU_cBka4|HHz@FEIjP; zAbf#^pLC5OJkG*Txx5HZu<+BaNrW%5@G~wS!q2hrx$}loe=T*i;s>~JsY}9)O=C#(Hwp z6-4+27Jk&png%EIHW*AV^+3wvE(Mfi0Vo^UN7 ze4T|ST{m4{!_yn|1Ps6E`Z}K8WZ!(QKSB5g3qN=Mk}KT%B*%^0Ij)>LKUK}0f3BL7 zsfk?riz=78mUBitZ)iDg|Ln{aFCTF5p64CYv;K>|wz0W6$Du<{9CVC%#x8pO4&O{* z*5RG@PPKYxcpqMkixF8Qf1BCt+B9jCw{5b`v43{l>+d=^Khr+v<^8iWp1CRS)zlyd*Z5JKS zir_~H{IkwB)qb(cvdRg?DX91jCUr0k5khxPWz^PFJ77Tjd`CH;fS%O zrrWkW>u8q~QLK~~ECs!hn%2=Y!Ou>!l1`%=rvS@AWt{L$I*y(>Ipml?13x=8jdCO+ z&iQ6$WF%qOG=`L@wb$~D#W$)t^eKIvW zGs!x}&tS-9*vZOy25sP-8S|d{YJlop`mZgabHFYh~GCLi9 z?-Z~WnV#+%J?5D91X{0n#~jaleUldhRMF>oUjRj>nhu^AJl;sPayaHZW0$C)g!Vw) z{imLAOnI)&&Iei?-m7!7eth%Ih$9u1k=kxNaBa?;7(YNgaR|(Lu2F%3?E#e4!+TMA z-V4M<^Iqg<=O-^Z=4UWCW+w4wegcGnAHH+1w0VLN6=apG@oNr~q%VZWxW(_822B~|Jpr%p z)_J@!Pk=6nFDAvg)wwsW1%(;+aYlUCi~|EXa9eS!-wX5$_{K(OMlZ(;1H5O(4}6-Y zGR{wrqQyb8;sxpNFM2)W{&=49HBf<&EfvPJ=jtfx>zf_-Wj9iJ4aieJi5kvK#scK^KArEb6% zmj)p%3+WKjCqf1mG6r-m6Q&n)TtdDhGZV9M4e$+xLZ>{;3e2Okp24)z;%IAYJ0I7g zGyHK4Uc_|_f8+Yui3t#kkGP?a^l{@TBeA2Saq}o)%RG8|G;SRoy*%%kB8Yg(8XcYR z@&3S+4-{}#e4#)kyeJqQ#dxQF_5=dF@4`F=!ssYpiwZr!KNqi7qA4Smqmz^K6QdH{ z28Qxwh{tX>5bzh__B!`VqvciSnz1ORE?P5LU){21w!PlWH_I_IH*gO=D;oIbV>GY< z&1yumn&LU)m_8*A=~Gjl8CIsa-ak9fk9qlW0FP^FSn&=D8sijiUJ&XPI7BM=-OsSK!Vo^PC;ftb9e-Y5QRNze1j5E=? zGze>1Sm)9qtY=}p%Yd+vg$*tf!e$mWx-0>c%ZmEi;(8axnwK9Vo>=0GIW59KSJeXt z%hk<|sC!=n--CDM+-Vg!9Pl_UjZ523oR03-R7&6(h)G<>Xkc8=d%;J{#I-{hD6Bo$ zs35Ww@KZK5JT(pBnS@A$XL({-+LSNfM>KyaZXxb7POZtmPq#?-J^G2BWlyZ_#-ye~ zOpZtoRlp=wU^sh*y{6j;=jLYQielW=av!OGO&^9nQuBm4d<||+HOPl|YJ$D-6S#&3 zvBVfJz8PPD20@~<;tN(%u!bn^sCtv5#*y4rQls@f}dE?% z#m#Qd)Vz0)=Vy7Rh9AHyevsa4z+d>Otr{8}B06coCyd7}5-QOH>$73R0U8-BufOoh z3*ob?hLU&pN44KEePH_5(28Npy0uU!8i-l<3Hp6&X8R52b!Yg%&0}vJLmbNomc{W^ zN2g%k7TUk2HNJlA%g4f9tJQTNbRhC0 z5%4b&=|LU?`x&RwY`ssn@HY07EC{}{OOHER$MoPF0wIp>;&qCOn08?$Pq+!0S^71i zl`%?|FpO|5Gzz4PdiSAv_mPh@py~mBek>5z&(9D;$R9vQjm@6`{6{wM z_bAd3-Dpx|R2;wT`j=`=<72hvY5p{F<EkkhVoVL&GIOcFeX zh`RZ}L~AeVM7YO4gIiob?xjWDhQ=gpB~H~QVWRlRDp!MaAQ+ac8#}J=2%o+A*i{PM(A^5C60zKL%8=*CL&1cj(LyoYXE z=vGTN#(goyW*a@y?Jw}}ci{F_?zd`8%)d2ag88i-WBs>!+&;riY;!R&CHZ3*4rxZ5 z!-9pU&U#EtplR_3_)pG=s&dSMs`BtSW<*ta#Lu2KA_UD<=xo)41|Wh*^JvN>qrn`_ zXc;I}5(RdtMpg6bdCh1-jx?)D&W&!(Ht<^D*^Dl=Ov|#lgZUiIYpPQwlq>CWtL4#J z#T_dIE#)e)q@cep30gr{1-i)-91>aOnKXOPeGb6mHn zmlm5>Dtknf?rs9{)wGxiLF1SaB^DhTvr(9pf=m%z@GM#!V1ujr%4cM#1zy zj+7X+>@ltzyEs2{iASM1ww!KoIQELAv?$8P2k`v|6z39dD9*Yi_eTHM`eT-|PymMuTQ@+9Ui=+FTJnfa{E5haK@s0dd{4E z*Hm)bR1!0l3F@-X40!w1mp8nB=%>D4at?Ip{;tEaFWdA74Ma8L{Iwz-t^h!`E)vIK zEgm;xN@)oG1pod@+=!z$sRmT{**!dVkNrkKmg()rVJJ;#x(7sVJSva+(F1Xl;g>)$ z8P#U7pqa&z<`fO}w9Bn>tGB7y^2&HFG2})P(_(gF=*ZB3xH?ZU(9;DuD8!rr$cz%g z--Luylqs>*HCjs4z!#54VlMk6fU^ENqvzWpRIn(pLz(tml5=u!fcp>e8!0MuJf}|!SV(M)n zxf~NXkqmWe_IbyQ@4^KzzYyPgA+|QtA`e1X{)+Dk3A`W>7DZoOZEf3S8Sl2v)(gm! zq`o8(^GrSOfxwRh&~0XZ6m1;O-rCW*t*g6dd+!d5pS?(YZY)*AXb4ER4#4Oy`5BnpRqaE+ffAdR=d8>sjcXL`l$!YzotG{RYyxQERa_ZvRAdw** z$^iaT4}lW6g1Gj%S>H@t2T|Ij7iI&wct8 zt41v-Ux}(k@ixS@adVn;a>7C$9Ls|UpkMT(PwViVYf1!%dC8Q zRIj9^wfqrjt(nsv1DzxeE{SvJ669_K(~`^+$|Xfz{iv%Ub6tUTHn#zoY3cl;*ku0$ z(`B)A*5k2d?J}r3_OHc|TLY4k7c__(g|@h=?O`zq@JJp#)8?BY`TTPd zEeVz+zd#_vKDCKt=3yQKFzN@}=pF57W51~{JEfOJqI#f>gyJ3^LO}^cusHPta*%=B z#kd`5&z*8geVb=$?xN?RL4KiYyWsQqgL%pFN;UDf1@n_HBM~U70|x8-ZKZ5cRa3vh6R**0q^+hbo&~8)iG8ju48Q#*F*O>;k(M` z&?l?dj%bc??^QpM&j!f4=n`4ra-~j3Z0j-b4?g0l{rr1~&*=77L1aVRFAIu7_3K&r z;ivCrIYM4YRTr*=ha*o!4n;czTYc!@n%4CC@mG$A3x(3I)ts&sZMWi0_i9e}ind4b zrhPT1eMP(VbKh)R&Dpl1?NY?q2zkqD&XyHzvm%c4=I7Zp3)(fk<@Kporouhn?2GoU z<~6VATa>SMtmd_>=v$Sqwy)-Gxub8sZ{TujKQ(eCmG6#4tE11vDm(5JcP>~HQH9Em zrIw}2<>!U+L#ug*R`iDzpE{RzFSXq=2<3-Y^A4}*k0d@tCZki)5n6Ux+yH?e7PeZ@0 zefQ~CoZ3nFCSPU*7}v5BZ$n%=TT+97J_Q1*oa8k!aXptv-J2^bLynbjT#_Wa6LIIX z!~1q1gK^OHa&EXz$$z>vz0c!IRk|2FHP%iwu@G(z`&GNO>{ruikV|t>HQecDdctGR zh$IlqiO!9M^1+YUbf-T>qc826GbE=HcLLUkk(sri<`B$NyRd7Q>a^x4H(pL}VKxZ$ zlG~76>m0Ol2_b=~7&?Z9C4>#S6FE%ipg&=Qh&C;iTzXl&AhyCVzXRia90VjqF<@{T zSgnnniFQS;8elAN64PQBxEr*l8Zv83rVfux)5Ur$NU0U&tTz0G- z{z{s3bUWUCgc`F$5d|4=uH( z=luc4xDUGb3%<#DT0&wiHtmp>YogkeK$G1D*}RN-z2j_{%Ec!(maU$M2TrV=utK_= zfqU6BkBOd1lcHs){L2~Rvf`Lv90_tlbZHW z&BcjBYO?WJEJg{=7%h8YGvc)Hhp4EwLx)ZrA3ZVfVKxUubT_PzL?nojgGaru?^@;OIMsOjhSywJELISw75jJsaF79M!*OYhfytM)c^ zTdd;1`?c@a{(0i*Zs~zfN)N1=Y%8Ynb$juey?bf=<0p}0|1R8YyB=uNS-YX4HSLD{ z$zJg0d1RoqzJBtRlW!l51itgs2Tv_&e`NmHynNtqkNx;qEdTHw?UDOATvqW%ub8 z(cYsUp}LPfCfCM@$1ajcuyQ|%yT`VfHX$hx&a_-~B`EcrN-^6cmY=h>Gqz0Wl8Uf% zG-Ck4-Qnn!%sx?%jzas%z&P<{LU0KT%Ts*lFdtY|iwEI+`ERCl<`VMN&l+Kj**~iP!M8 z;r}ed4EpzCsR3P~n3dDaS%?2eCwC5nJX~KOPFCoe0Rx_dBQ$`y6jdZrtAWss_Kk7 zldeQYRcR_mN3f}!6GfUIsbJ*CRCrj{iSzg}+uU?X5mlY0`53y9vES`)iM0Fxq5!gjg z>tiB5bY#Cc0h5w3Ze?%XgRV12P7aAGM_Pn3y<=R*h_+&Wrdc^|XGsQ*A2~F1VsPlJ z(=MrCM1zdDLF(YRX=YRuv-@ElH+t!cIGO*DpjQwa{mdwt$E8jBaWmO6kwqIH;Qvd+ zV=5zY87t1`vPQ?2(q=rcnq%|C6*SfF6#CdV_T05p-L_N-j;%3EN2mc-1L1}@`l0F3 zSzdqUm1n{^ua3MOT+vmpoAV>u@D-tAt5DDpGj|Hw&NXZ9jic9(zHvO%xTdqdZC%lo zCt~$37cHBFf_*XbenGo`&7Obbx$DopF%@#InX+z_UN3#49Fkm}Y2oy1PazE^`Gp1{ zyE@xO=?2h5!!n9qo3o2i9_MEZK!OUb_BLXv><~ z8ZP_LzM9>(s&2!h$u5{m1$Ak13Pu;OON%?3f*lAvF6+RUz90_7h}ql|Pz!H`S<=BU4S&U|O_j+QMyBV| zO71k9AF1N(l2&pJ;tWFyWvGDF^4H|=W32AfC(0O!(VQs4>h3Wh$t6py_)yPs?$|W9 zNf|O};9S}fl`QH^HRZXaKK7>~(VJ7xsa#l}9)xyxPBUD)RYhysNijF@DsIg@l-RYR zI5okixOC?dd`?nzj+M7w$+u9-dBFG4OcO+VWv1I-Y@x+}2tZ7W!G9Z}jSH;WaW8Gh zfQhWM^&kUDb`Z)DC&89jC4)cSvE&h|I_{Kq{LPNv^NaX!@GSo(eu6#H8jFDP(~wz8 z+aeOsr5y&6MLQGe(R8?5IRQ>hNtW<_%&C|~FgJR}0;FdIJSYdT|Dm02dT1ASIyg0P z_0%-XWnm8<*RgjH2GN>KR9pQeLUElRO40zE56H@vW@)I@*#P`LeK(5oMXw*rF1aaW z#k#bxg3)$rQ}O>3QnK;*V+2Cn&$@R$;MDfRs*j&oJiA_45~+LN`Hu4&GmEN~Lgz0E zOTIC7yJT>=>u-1b^^RD{;LWj{V}F|R=5FEOr#ddnxiEgicinem_WEpOEZPyX*GD~f z?M;Hc>EkCtO(3Dj;enpZZw~p^3|Zk_cMO$Sl6|5tysyK{PxYKBZ_U{MlPk9_#`c^P z`cHxWo>uJ#?Nu4}t3ZcM2Z#=94yb*V3;H*eC_YmTVy8No&3iA;``E4* z5zT`R;?<^oerD2{*kU7^dNWqhsTMJn#0B7@SbMRiBGeR_DA|oJZV<=v;<$U=Pa3U+8;RG5iI{v|vLhA`3ZzyIwDX33woW_U;Min1R z?7B%Ge+wWKee9seNA>YmWgn|l`_RX9XL42wEbRyO;&*w!_+euoYvqEsA>dKLXagX{ z%dNsvhohwq^}Ni@%2NgydsPahB}h!9HHCnJLw1r-D-*tCS`?p2EOX^4Ntz_;VKktU zIO%4IlU5~+1E|bH5;nxKDF>{fpX@0l)|w}L;HiN#aMsmhv-2~gXCgg`cRT|f@1RyD z&Q@fttpo3Lhr7OWw0h3^)46Qt=oI!^w&;*tNZs%uJme6m+CLgT`E{ZX|O{I zp;vjAgBj6;vLquBHlG2K)gvN z>tIQ{58b}Y$h7;W&FM=O;P91nV}|TIDD)^SB$V)@Q&51tdU#I1P|4Wu_CI)t|X<& zoC=Ht6N0!>1otj7f6zTNh$|DvL$d=0XOQ(yW4g7l?Pub8GuR@Dh7}tE6EaS=|BFeE zB?E~eU?R~SaV^8>l{AYodc|6u5iJ@;q?8je#46E5aUJw;@QtXoO$bt}3;T1l95!gX&IM@pjy2uq{87B4N=Ez_c6uL^rJRHklPRrJuJq6bE5 z`l5|^Ma5v9;b2*9j#o;F9vfwBZhCy&=_A}BDT9bR4TL)lk>?0!8WypG1V72rAsV|3 zxU|!W~#%GQ>eUa*{!Oo{TjUFlP&lvVCRzzr}af*as1SI9t!@&96WG z%G2-KziStYwy)^6%b0W1`IhsoipZtKy6l`}Dh!CYj~>{I9G&nQ2lI(K79>f!I%Tir9m+OGX`ub`3C;OfG#ATvF!LgnoZq zzJQ=%BH)DZ5=hKwA46jPe@1zOYDZJB!6Em7vxSkg%&1J5OB4?430Qu|wY1ZF6KeO* zh$bQ}4a_99lR3aqIYa(`!*|w`&mjP#I3s7ylW5+$&h+|IUw&#KaO2wbYcX9(SB;9fQKwgTUrPs;z5Vdl!TEG%6FRL@cBd(d{P0R!|%n zv8kYsO%FfPWzulaUeB?>BPY|-gt#;T6G0qPsj~00dnErJ`;FF#&&jcesO+-f&WgAX zSo8-Q-$HC4`(}|bbPl3=SI0>e@%<2eV5#0lq7R6AFK=_Jh@eV58cN{SKX zueCBCm##o&Y7H}~1(fRmS0{u7gG@+}r&J}MOOR)`M){uReJOVkLxpWVS^8Pr8r-eJ zDUcXZw`~TGeYJNg#smpe+#v7DT%lNan}b#1IQY79CG&^kJ|?q9fdayPV2*Z)sj zCr8;ja*s~}50uj^>+w9LA}jM=2UmUq^Ym`L_y1r}fNkRC)}MnANxWpS)92<`pv+OB zw9(7Cr1vi4CF?Sjy)aX1U|3N)1mLuSH8__rW=J#ID2Av{pIljOYP3-z8Eup@qm8sw zaxFf$4a!p506GitawpmVc(tA5o(FHuUuB9jlzB3n+F(33OiJ9DGb!5GB-ag))XG>RDf?Sle_^WMfNPFSuu!t<&xe=Vd#-M@ z4c4#_Tc*$vNx2A$3xO$GE3GAJ811P|O_K_lD9gEodJbhWD(i@6z4BRUN-wvIScY*d zO*hoNE*&1~U7rp!wLI8-okr*8)w|TBLLFx#8DCR+fhkw9E-&X!sH)QI-;fRq`8TFR zz`Lf-1P)?{aas=NAZ-#a!n*N>4E1!Trvc0@$#lRJ;^Cw#wZ2H1(!zK)q_nt#YeP$8 zrpegS&FOGZf|hhxsX4Qj)+zJa(9&AvS2Agv+^nTrkyi>V0kDy^k6%xL4& z)WWWw|Ckt$l4U9DhUaYMvr?V>Ij!EF4hJ>dnhqvwbihsjvp2tsS(rQ$v1IbnrNW9}_t|8HHkcJYMX*ij5D50CgtbNj@h=ed9dw z^H6hQqlD-*#d^^P4?HuX1vBj=g^{g4SfiA4CZwRSA|p>jOG&q{r z`Y~vy^hteo+?Mo-0=Y#zFZq}(Nn!Hk^!!x7H!4~`2WypONyMQQtD-QiJK^a@cEqAg z-Zy~_eO>~g(CWvbE0H5h;t=u+0}U=3lB~tZtx2#;33JnEqUGHM>{xP;rBHCoz75^K$J)qmCbo(vc zh<5S+fo|97_8D$*{g`Lo@0p4l2tml@q zQiE}shzx~tvUym`q&12eLy))N2E}Qj8oZ6(+Ub@>w`}@u$Id|b|HHNn3~MM$nQ00& zp{QETJM+Y;Qzu<#2M>%MKQZbaIR3=onYd=s8{o(Fvteu8?|8%lz{eL82;+5 z3x~ck8os=$D@NJ!^`YY^TUB$+zW1G}uz$JmcH5pC{ssR#Q=vnGeeW*}_Jq~VzFXUG zIfbI*G3yCIf8ys^y$c!`|GZhYQrx__f3SterPSL;70IzP$=CK%i0?{4Au81hO%{AQN;LR-CbMbC$>hp1Va8{!FuF@MwNAp zwBDv;s$ZF`3s1gL5ow4Pz1O~CawcQ;uV>|kd*66zVOFTIz+{h!$SWuVBifDEH;MO4XRs$(%Uuw`}8 z!*@zsueU7Jufg)E%+_q||jvid>{`QGg zOGixCx#W>V@~jY9QGN7FtBxL_YCB;@?OLsKvHshA(RM1rHY!3F6`_kf3Rr+k!*9;s zF||bt7j@sRK!D_;4305U7&W|CB@{aa=YUk3h4x4efhi|26$GY&v;)?K!LOWudsf*L z`tX&A_nR+;Y2-B6*X1vn-;zV=4hAMh--J zqPfxi(Qct>&n^8wSe9QBN>0S=LxOSWz6mKX-i-Ez*;PYjv`}d3TdnS2HT2)AUNP*K ziHwk26YW`SU#;CK)R4vf?z*+QEkg6&)w%(pb|30!IY9Vm8zg)*461O3Qfu9Vam)!G&STo# z^N1_4qc$PyV$v5(ghkkiNlv)C^ zc)3+rSsIn{GnOVHo5HSgZN@a_4QVX0+=gVu8Pixdq_HK^Ko*)Yja`{Wu>nDo+*TmB zL89F<)iFy6#|@A6OuoZnx;1CeO3GC_Go>$Q@|e_?%4Tw}ob>o;!(65OK~YZK=H(m* z_XX2^c++Q_`ZAR|MV_pHs(&O@_~zdfYQC~96i~HEy}@I(X{zj*aGhQ5#5M@DQ=zh5 zH|ew3+47Nlgzn6P8MHX*H8er=^nd zR>nC|hN$pGNaHF+E)A&|wvZ@WBULJfx|J)xrb)$8Tc{!(7ILdhhk$n}QnBR5M7P%E zQ09eG5URIJbPLk4U9zlvgga|Ylro2~6?xPsQ!*Sw*&ro`hKfl_Q%hRQWaf2DW?rA3 znw2nJ8%3kB0m4w_CZPlt;9DbobL$XlVj(?3P6{z2g)PAYL*(j{JP_0N3DL{(@e_x< z@J=Hy6C9UjW-lcCpOcGbX>*3`p1h6E0qH+D6gMT(q|8UuR#*l;+HE0Lgx!eC)*Yhx zTP+?pF>H))``lGcQb?k7Qu?oHj-n+g%~4uSCCnW)mEkk&XQLXGI)@dUY)W>kL(GvO z1`aHY-Pq_sv*I`wJLqUQ`BHW?CLv9xZ6NN13(ZQXyz7SQ|0vKybfO){wq(?t`~RFZQXhg(TsQyyT=c zbql}ly z|AG~pCVgh>`99u=qVQVW{+eG!friLiy-wVZMdGqx>E_9K4U$0;&!o&iS%sjLR4IM& ztYn!P*@zbp@4UMh&u>#G(`d4MDrIj@nW@=sCeIu7w9yuAyZ3(rm>2g2OmC7q>irq}Hn<+N- zMyYizh@Dd^lx~YX$`b~5V951;(-%w3c76Ns2(vED#(=bSD-qFRB8*XZJvrOEHTyi(CG0~E4rqI-mz zZGhQTuvSnOIrPm@A-_I)nnVdrl!=ovabk^)Opbk+ch^+^iK%|EZ0YiMt7ITl=UggP zE+xpL1bJeD;~!#ZHGE=fSZrC&S=qAl(J4-R*mc*`^ogk{QIA2P;9$&rNYEZ4Ia5VU zR|E+|{d;|j9jj$6E4mgLrjXtCUH?*FtbIUe+lSKZSCy}o*F?MDJFz&hTHY!^W`#O! zr6P7v5j!AS)0Vkt^@n?^+rJOG8pd(z5u(;-RI^ zCGXNO;P(}-6_!Wb-<+Y{7Swqb>O32Dp1}!$UD0j`?5f&A4cJF`TV1x^uw}6?*06(~ zYi_G+*S7AWV9RaDP&)c3*cwx}C7C;nEp`z*h2f=o;6UK>%;gnk&2ft;BZpo$aPgsq z4&rdU=wPn%nVB_5jLHrJcZ2 zIX9AB`$+HGFj}TbF72X|0XACq!48yJ@kuK*gPe%jYiUzf!leFS7c}iD_5(@BG@Go8 zQ=#gVP+o6RRm&2JnQu>RSpD>xYjWujAA_`Qh7kmt_;3!FQnzCW|rWaY`FyM@iS3!9gQ zg~H}oVPDL`wk?~(4UljW39^J=66%f!1xI7%V}kbBx+zZ-b3;jNYW&31n257mDCmos z`vq-3?Rth`xRBkl=)J4!`b5{YuC0zXkhd<9wbrg$>I5xZP-ca7Z&nEE!X)CNtnB(j zhM73IGC}0y533v+R zlS>%mC5S)DkszaUy5ZBQM3Nb`l`wox5NMalt%KOfjM}9bBtiy~5HitWATV~;OS|A< zkb8OJ6!HFP7j}Tdh?G`H*rBbTwYn@2En2ay&`R41A%Hiel+-5IV9uxzaH?E(WxLCQ zMTp_{V8v!ih2S=!>{&1=mwFdM-X|fk!NN&tBI(Lz@p4ed6xc|c%LH+Goe8A?>S}9r#_OhIm zcvmUIoU;snoSsH$mdQkRfXKE6FPWf!HGZ4rq~W z{m9xWMWjomW0KJ(1U`>>CgPsH*YsORBZ_zboI(!V;uc!{kBUA~2D(~?&c*W~P zt0I^Vj$ML@TxPLvBTWioQ9t8yHBI;F7QxOh{48qN&oWlSc)HcazKOF!f})~?i5kBK zy1rXQbp}piZor)!NNeE3O6#%#t7<`sbi>^(NF-lp^op%9FyM7-Gw~Si#72Rn*K@Z9 z^NI`xzape@2aOPXOK}e@eFJ=a%b0^JLA7D*s!s46Z4$H;*V1V@rMQuPjGPiQ6FDU} z{?xFMooH8=k*NrA%ygzDN>Vk3Hnu3YQLrP?>_KCjXcpGSJZJEKg7$e>mh`rpaKW1x z6I~lVN}h&a-0;Dl7)ktFfEz54{Pk{?ee)*$2zN-I(j5%HxOtL%dF+wLec7!+T=l|3 zb&Dg|^pd>bVCS-uYyZSPJDigNZ&a|jh;1S}T41y@ptJaF*uAd;Wv8qpJQNVMF7=OiY@AH6_%$Llv6Zz<8(fcq&x zLBnv*$Ym8QJQ;p6;*AVP2e9&oHz9j==+MveI~R=bP55S2RCmWzzh=z3VZUw#PH9D6HR*XGsMyrt3vTAHu8eB2%Skv2HpLqpBf@3TCbeee}X&{`X5hDp}edbM6wF zu(_11h%Zb5`ab32u(1-p-ipBj<8S` zKQZ%daZGroeehl*TOZD1o1*W7R%OzILm0EP(_i!# z@G}Y>rW;sTj`{y)t2n1kbSlA?OUx=Y!9l<}bozp{;QKx$8Uk*`Eey4!*F+BDrLyn5 z(PXitiYfODB!MwnLHw-bG@N-`6J^+Odn$?G&mvE@Ec-J|!=!SA(bW8#Hk@B!&ksKX zt1;#UEv$dDGE}#&#y6pG%i@`3&ktLLmc1+L0qI@ql16CXv!dQBJvT1aE_uFpb+Kwi zy<=T%Sr`=Z8dlVezp|G{o`@ca+1mhCXO9$ovvozsh+0FOt36nJ# zpRQMLU)IN}_XyfbG2@E%m|?5Xg;NKIC`0qnH5;sB;apo~*+Rq&0!FogTpJk+!`{gG zn4wvcpd0!TUnn{hvmO@ohd+f)8zKl5-7!PYGHls);p;uM%2Gx^-~d2vC(}`%VM|CIT$NHDCkSpOy$wZ_g-GgS*_|^F?Etbr@frK}wv}$e<-0D?!trm6P$>~|pt(%G>I-y!_)~f!P ziJH}PfPqdlt7up^uv)iIsNIiB!=w%c&SHk1CK!6^IYU0oY6q9*@9O&=Sh(En_uDyr z$?tyyIf$jnPtuCNFU&vO@h@abN6JW%vn8+lIK)@9t9yJohL>2@20$S>#ttUVqB}9I z^t*^X;PktMJ>c}aQH()^0F0LE!B&VdV7gES))XAyoO(DnZHc-wv5OO|V^SF5(veR9 zmp(Oq>Jo=7dT~^1a%Z3-y@6O{L^}p*(ff|K`g`z%wbx5l*W`)#HN-6 zaZ^NQNk<er9R1a~vA>eG zY?Pm5gN5A;iaf=Bv!(Z&%brY&`YHBWQZFi;45x{^&{8S8^jZ?OYoZGp>aC>ApNSf< z)JkcEY`{nnp`qp^a7lrScezP8cuEnxD1|4f>Es1H4g-MjNxV)$)Rcaa_YFC2V(Eir z9a~7{GYm#Mrj)y2V;R%%IR%H@9NU{J3Ja1rkO|ic+1N-d$JlUbAr4Th&@I(D6!}qJZxb^4$dLy#u#p4=w(DOp4dvBhB9;-iAYWpV}0XgCytyr!j1?y>lzq3 zbMU0=#Gq>wd!68wI9`(Y=yIPPJ#*^#k+Y-62i=3m&tOxOoNn;Rv+zVLPR_aP?Lik# z8yGz^aN^W)Y_-xcS4sS@QGmG7=NDTPo4VMP?gqMx_KAcH;-+35+tABc2$35W7tXn& zOp01~^x~WcJ?!T_NX};VuVc7|xCdsneNSkN@l(ltB5T&-NFI2eimoO151&~&A(;1p zO|_BBNtFT4YE4K46}aBCF!0)wP}&JaJxl&2uTZc%X6_TTeE_Go3f8(+UHwYa{uSMR z(&U?47bk@76RT}QLhDHYI;E;xuiGQk?gg)8+DE*Sh5TEpb-1$~A499UvX#n&GpJf@ zNaVOJ)Ops_duhyfZNjQ^1&M?SpFDT{w?b`m#^Y$ z72)7rQ_Ux)n&@*&`&Sx7=UMwG3+zRy63h;2CG0&>)7}#`_MRl#H{xH>)vyw!HE-5h zR_=nA(iKoT_-j+^3X#r~C9Ryy*+Nd!s@WN;U(*@C@=O?8Y6>E?IBcSNwWN9R@=D28 z2DUV^Ekgdf959F}4IdK91_|aN*4>9$cSBFA;YvG1{*h(}`lpM=DB~aN5O|b`SLv#h ztuxDzC~koS4uot5WI*Ax>tU97yaR~KW1i^n0rA4stQenh`E(XAZc+0+`dNmJ4t{P` zv6ma!;Dk1Bf{nNlrH5uNlLJASMM#)(GZtY)!?r+xA(LEOB(xhi`-eM4jg@vW_d)6; zTZUMQDO!#!=a$NFDwwf^#W3Wk86l*a$_91%;X2D={ZXT?MG<<@&Uw>5EO2B>h`@NAn&3@90K2i}{X? zW77J>wUiwk{9|6nes8vOeU^_~m3eQN{R(9B6>5ahN$)In3-H(YOMu6Qa|r^>^`P1E z^|5drIU0Op=8ma4ip_WATtEDx=&|yHz9sWdwk-$#_S%oH{Y}5H^C$$qG4pXjdwgA8 z5FTGqmqCJjqvU!?xZ_Ru&|f#(Z#ci^3?I08J)v^hly#W1Wh`yNXd z_IHwL1Nno@d8i|HwhaegPGfa7B`V(Ns1pB-H}J5SsfgM-+Gxy+H&KWzf7!O-OAzWM zO6y=r9l`wMnu+%Y=J^?R^jb}V4uZ77$-(4BhsSZLgGA|9u<~HUP|t{AA2UX0z6`De z_+UQ82=FXh{79wAPA?xn0ldMb}@ z;igDqv_4w2s1ht&poKG77Ot*fZ+bpVt@FZzLe1{gGFn6|U&Vr>;E3v#OCj&C@?gK5 z@-cvq`Gcxgo(p+@X|ji_zg`;lzx^^3$CgD7ywfYxZeKPo1wrxlsT$WBTcVST?xp=p z-ODOaQ019pB$Um9VfxaOE3JLE^PFqNTYjriSzAH}ewAJSp>IhSYuLSfF_wMkl_RXM zue~I#1@hl9Ms?Bgs9R{>f9v3_Ucr2vR!Bo^g){^abMBW9->>H?8|ZAzjK`GyA@o$A zk)Dd{LI?F8TO9s-gyQ*^=RI(867;e&YvCmt{!aY-VRX&o5!O{AtUCaSq`&iO)z16u z&YafL;}U2q{oc}wzi_2}56(DMJJ)vaz0U&T6rv=rB*9_iH5-5ZTHc6BcYBjPm7Hr&`i6!dc4*Cke3G1=rje z^90F)+uGFhseE+ibg3M(#G8u5`f>8qDxH)*P7XLP4Tm>D#DuFN`2f?3Dgn}|_nF*6p@nbH_)rWF6 zpq$yReuTg&&E+IZjM=KpolPUaor8OMr*8O0=K3D15_3J)B>pDp7hqJ#B|lXxw`216 zTw)aVg8Q4xr7?T(zeULKIHUF8e~y?N#;R)%V7$lbq8NSd%%d;QoePl#yT)PfjFFZ1 zh;o9SjH8~Aawx}0-lk)uGBZT9Xq8e$bnF?>lFWHy7p!=lqrDjH5>Hx?=;PHC`j`tS zn~m4a%i>U$g|O<_lGLaFU4}lb{sMiP&#>$}=noOg{vx$!He#6!doItN|DUXHYLxA9 z?A#yRH`o57^vy?7pMWBY7h19Q9A;DT!ijMbmpWJAE)eH|aTp?`;B1|{0617rbXvLd z;G7a>!?`*cCg_y{rnod82iKbdvys7UQgU-Cw7{9@+ro2l*K+Pczy@o5ua0#xQP;wL#(CU5O$bqD1UuTxv(Q1Ta&=!|gX5@-IJTFO*jhRwU6 zKPj!=ni&pSy=?MoTLWL#|F1TC0+jj>kCks%v3j79$I~&9&jR{Y*r@I2ZlLg_P#a-#z#>8OY9)O2sr%t{w$9kDl2S%J$5;9-ETpBFuD**C)fPy{Mx; zNnMgFCCnR--=pYYnNMZxZ0iN+9B^?f@p8AXj;%F3oiIJ{>tUi z2_Nqdv|YI@o4ampgVpG`7yC0V(N+=fIQhb6O8Q`tY?Z;R04Ro}lHmxs zcyI(y!pfE>pCM@;dgV;WVn94JX&Q?@p!#N|w;)X0xZn}?7M^>6ar~&VNt9t}3&_^CWHuW%e(?WD@SaZ8N|7Fh^|Q~3 z0y@Xol*bQeMSjQS-qEcY&gx2F9G#*%KjR}adofY4KSOj#nQ`PFnkwaJucld^!FMWh z_CMT`-U5li$Mk@#)#ROBu0%ax<)VP{N0dKqkeWGIAq5;~1_y>9mxnAHhDcuOU0BA$ zFSab)Rv;Z24nZ&IWgQi)kOG@PD98k%Lo};u8=rlCMl^|1XbPCLUK~Hcf@BO)`j5PU zi_J2Pk+hDaHSkDs`&Q5d-*js~ZY)XA$=Z5;PLWYkMIb2*|i<{ zxcIyePVYroKQbn0j#+pUpoD!=C8ZXYR47{&HI;JhO>{7w1;=2BsF^@O9RBX0Z>b32 z=jVt#T&5dOH$UA1xW%;ug};Je@Wmu_Hm2ncXZc_diDw$J!Jm?Q1`OX&9@1+7-N|4K z7GUIboeedRXV7iR0480(!B~t#H!e;ij8N%=Hsx4vd&tcF+N6@D41LjLO^GN$duo45 zi6tydO)O?3eQHBtUZ)mXz|E--TE(qYQYV-9q=IzaBZxPk7YmwTCE0(6dO zVLUuf`D%$O#7%S`Wwr`N7DQvm)$?<4BVpbs#!K7|loT<7p`@s^tEP;u5*z~#q9F52 zzXRE(Y2Qc#mvV{fxNPNS7eYk-13+T>n}-I{v;0b(A3n39hD}4>n%*MV4nb38Iid>H z{|YXE3T~8MFMV}XbZPX&`%k~~^rGs$^NSNp?(fa4RP1Ip3Dwd1?`-*COSD{QJw!%j z4R7`f=29|7Nb}OnTy=z1UpXK4tmukT(?S{7#?G%cvGc3pc9=}caEC2gBHi1gD>_(E zz*sPmC#9=euWA!2nS1FDvPSEqq@A)c+|X)4^PQ{~`1rAHT`E{I2-}YdmgAuV>)Pya zL1g~@;5)&^>i1p}>m*e6t!Vq#wMFlmqV=)jwmaJP`vxw%^;0`p)}4vAt(JAH7IfUn z>LhsWOS;A9g`T5=<=7X4x9x#ZowFx2A?j-4nyt3})I=JYP;*0Kv1t_nri?XuXolq1-- zg~r$QICoWm-{;c)TY0xUKdt?T$y@dn{mJ$0l1RPK)Vo^U8_V7inp`*A7A9{@U7w1X z%OaOo%#P@x?;QW&_)^ZdPcHda>UQFo)*CI?Tf&#$Y>%8?F;_BWD)!0ToO)~Oc0qmg z=_SLDtRGt!zl8qi&tA*U!zQVGvgNZeTfQu2%V)w}&*c=~w7zAHoc?B3XcCX+EK<;} z6_j5$uUT?eERJ;0qf5g}M+mHQ&ADySicmM4Z>w#vtJGw{u2N%iU{j8vC_FFJ?_aIl zzgATG&1;`(REC;g=?m#)_iAPL((^xjX+=K>KiUN?3k_&?Q%R%%p7m{u{uSdkdM@>GX=LD=6`_`&XElYqKhJJm z(5_Q1(JVrRCC{=J{^f^-%0ZN3waED&Pz*RH<8sg(egoduNl5MNRVR7wS-Q^khLa@NG*ht7Sp^3rj8z54iF4 z^{3z6vtrw_o?E__E1gmQPDS+6Qr(ZXe7t3;90R1k6}OyLG-6&G8qr22v^T?JxILGW ze`x=KU8ve~$F_$Y*Jl?+wC|hVF}?Lt^w^U2N9K>si!Y)QyUDx13ZB1Fmz;exVlA-L zEkem2=&0pT@nfn_Yd9O*uyrJ6J^BkIMhJKwEZu{3R79QAJ4DXFt6QKg(JRLN3>0$81N=s-40KJ(ofp`!1OrB6b!@teN4 zd~cnPHZP8U|GAHzTRex#?A(c)Z6_*}1v_Fjj@!&j^j;HZuZ?yuI#;?6|Fk-0J05CU z)7ip#uZ=R2)VOGj28E6zKdt>~fnYpIRP;18kM6YUS2p-Y6VuhkY(rwYoY&4P(;XCy z66K{dM{t}0joeb4ro9hVW5unD<4gNv#l5%H1tI6clTyYJQ*_{68v|1n)qcnHfhqC= zk~iZ(0+p$RXkjTTp(`ailM^lwiucD12SPPunRa1CU9t{Cq9VJC?@HF+;T*?)y|(teE$0cy|ZyY&l`~pNyn@+Og``amT##fsLzezOO^x4|1`q6I6x< z2)t*8#>t!zlk(eN!j^Oyk>7eU@(ebLmwr@A1XA5im9+H|f!sj^atG$HoGQ#=X8Xd# z;_(&J4ne(RqYWR4q%~jA{aZ&Enq4_d@G zV;&eT!96JBZ1F>uQ?x#jPpZyQGEyuF{~fPSP~znj$P&`+YEpK%ryj$~o?FwF1iDVit# zF2Ycqp2c!QgOIq8UM%-A0wHXwoP*`{oTiK$PSJeBC{hJIbizIWl0_B#LcQD~*B_~I zFfKupt`>!c4Zf?iBOztngk)MvGS=bhZRkh1{5PcJfWr_*_9!+S9)~0{ksq)?3SU%V zNd?U$7i_rV;UTbNYhUcAfgRn9;|%svVM*sb<@1ig>jfDQ0uK%&I?jt`jZf{)tO;=p z9o)!X^i2fd4CY$E>(}86GlmnnZUbCj6MX(Jkuz&~$feO}@G}`|STkE-_G`3)c)htB zhGSaug6Av8LI)8DkH7gsWPa6Nx2mnf3rkkG?#8aK?}GEQg%Lqtwx)%R@K=t82G2Qehs@7=zwa4 z@2%l3w{Dw8I_eLDmMCDi#-~DevoTPmIQWpnbb;9m^AixU!sScg+ML%hgotc~Pe?3| z1A}55Xab%|T2bQ!ySSE8iAQV=qEAFGE#hia9uO>|pI-tjhCTlS;*o!7aYz{LZ|8;2 zexqc?Sh`LeYwZ7P?@hqtx~?<9T3!`uLt)>5Eo*wMBuqOa>kKVJ`n}vB94A z&rHDJb9;C1eaJ{mwz8NK&3(*c<2?^vR$7E!vzH?^uKeF2(V9E?pV8tYUJu&IHyAhH zC2tOT1M!%L+CV(+UxPAt<Y5^sWrJQ@Y&z&R$bYK=+fVX?$-jl00LB&Nf#?|4%+iLpG&%1)!ycg+YUd< z%4Q7x;w|P0gg7-EcBc#mFs9oNpAqlZOnNF~yDz}FkKAhTAAJkuh&zf{^7jxTj;0v$ z=MbGXdo3p_yw($y-h>mIytWfnUVEJd?DqPjiUW)8FZq8MPwxIZ;@1^Rf((=|Nz-b8 zFuvsO-Qbg=nI$>`7Y>(*_l5sO>JJ8(Inii3ae_0)G>&Oa37I=(ZY(Jk_8|*+D(G;6 z!XV(U#=&t&m$f&2bCsQgd5)6TuPc_L-SNR}m@MtCs` zs~qr5{}>M=jpM?|j0-!vWt_J5m~~vRM#h`!vn?1n3X37GYM2|fF{LVll@Z=rQ z)a;jPUZ|N%2&Gnhsg#U}oO}LB=;GITBNwe8R3(K4C|1iFJzqgxOfbt8=XUb=XUaW#p7^o*D^>+&m1)DyufW)9tSKRKHpI2W=M&K(b1%7_X;cJqMgresC4HoSD{g-dh0LRp)G znOhc^(YyvC2tWhA$>jS($X?09)R;Wa#TZ!{9N1Wi-aZ;uSAO2mDkCFc4wAxt`{sW`W%nfdApg7yve+ zggj!2xl*nkxpE|s6>=3q?$Bg;cGKle&-<=E`K2cV>DT>p+rIkgP+~RN_!FXLy5Bct z2;+?WvJ=M~P(6aC4WBYhK#9r(b2qB z&fXKe4!lF(F4EXY->x^2z1zKRyeF}Dhc_ATDeT?pO~rc}dv|%$Clb9GKw>guw!`PU zso(tY-(oa0U>G$PVe7Z?)Qk*k+7*mtNHx}~tvLN}s7c0-Oy)EYG|XuM%vU^=g(eN8 z*fjgSdNz&Cq+ZXbKh?`MHRYmr=bVr%X9e#P=DgNsEk z52KtK>QbczyplM(o+401Z&9ZVTqbEbU8VCihVBHpfHc91wh$Bc` zDau^@r1NXaysN!^z4PnQ_KvQt^=y9evHRu}P%N-t$a89PYdwv+e>WR7WsJ}SASuJ61?{9hrUGY@Gd5q_~@e}H{t=i;NGtbJh) z6#C!nVYI?5QpB%`QnThh^I!F5Q9w9_=DLJgG_ckz`Wc&r|2-T=5>;sc-GbpL<5A-Y z!*BM0+Pmt^aw{`y@3CV?Rydww38ecUx(#B<@)0G5uoW{oYkeb=gZ^LJ$rk04xSIOZ18i6vr`oWr1oyxTY+a(qyq!H3FxBwu{tb(W ztoWq%do;LpQmJjqYXSKXD*+)Wz7cV?|SB|d4HHU*EQc5%GvV1wVv2FvhV!Xw`LjvXql%~ z!xS$*$hvW@wr;=%h6S_8{r~GmndfU_(!Z5;!!Oe;|08&-tsDNIDAh;g$!mrG7(WHe z*UHiWsBz!Yki*!N7+e3+2=6-j-}lXjnFZn7eEP33Ay5vd^+3&cifb zPKNg}dCC^giqTM}*Go^8Nm(NH5Hp=Q&q|B8M!6>PuoE39P_M!U?;#jU7Yh~qEwAhzcq7YBS+4P?a-?u7di4)%#je+ zB>eQ|BS*ml<=B868y_f#2UnSPow^IXMba2ZPd0i^owUU&RWL?xiKc#WMXJisudh_8 zk2YCy0|55HXrsT9%h1zuO-<@=j4d_Zc`J~k@_}+}LXN5xbLfpkwPqx0GXm zU7Kf&>QUvj(rc5V?T0~u8>22eYQ#zg+ahEY-Z@q{{x!&->RwMzWLv!KUWT}F#p@77VMNw zQ45S`8^JcNS`lq9F^a#+L;S~B7)-$cByGpQSWTAP`k{hB(B0sY!^qC~KO!xJYNce% z4jQvJJ(Vg4GTUsdfL~JTLOEja0x)^pQVQ1Iz~)67BEag!FH<_DBFIBerOCMz6KMPu zN~csrG0eUK|4$T=EN3CcG4OBj4h*KMq_ce&dZBz^cx-@oQcSj-0X6mx!NeP+_Mb-2 zp>#m%pm%`Z_!c zE(PMXClh%1q>WVDCb>2x8p4Mj5K~GK~2rbaOOQ4si90lS^I2 z*x7O989Orw9jHx|Y=fMPzF?p5fotVY9m`M!GZQhw4EP@9RVIzXV#orKbCO`-(Kd{Syt&D&&3lcQ6J zI8QUE#d?)scG9%u!D&x6d8ALFsswTs!@YvUH8Ud*wI}zd5(MD=w2Uwn2gjM!`HrdT zbtLWeL&#@fa%6C-OeZzuKwuvS9HH{s@yDPoLNZsW6AfG}2csb%mVM}!fKw9hrGQvw z;SJ0=W}M;-Pm3kREpw5fLgL%%8y|-*3m6LS1$JjgE{3R007wEUH9ZF$?i(Vxn-`!L z{`5b zsW}`r9ic!lv;`BX^a~Ns=CEmt99BM`8Qk0wsoWbj?UMtmzza%3uR(}eLddR>y1b3L zTz$DZnB;lAWbXX@=}7suP*F2%IYuo^AU&8|JwJHM(s0w#5aq1Twq0%uI!ouy2WuaS zls_EiTI9fOU_uS1Hb$IHDA&?_M@rnx!kZ$_Z4|zp!jD`&5=_~8J0)XwC|J-G$=nu7 zX{N{>;`j&cmG~|s{ufNInm-=0*HKfq+_6BA5c>V8%J$3cuv$3hn?DjM-5%z4ptUmx zp6Q)E2b+v?lPLaJq;yx9+bxGx&Nl_?4@9aChPie*aMOHSaBF*{`cRlVEC-TxnqVr- z)6`PiHp?AiW4kX>xj)Rc%8BDkVC`dd?T=KohB-(*iH&9{+alEm!rVa$JaqX`Fllo% zDI=I!8%d&`TDDMKEWCk**GH1JQh4JXaO6&1o(iUJ3net)OxPc_+MXS`JQ7T6xt*33 zum(5ok7T!o(%O(X;h<4&@mBPNM1zBwjUi{#E$7albLV0qq_!=)A=P2c5ojM+!m>EW zC#BX1I{?v;Vs>`YK=(HPpf(q~)I^&kBUl9B1r9FJV>n%eZXjV50%0=>g`jmy&FF)bglREDeA)lWOpt^Pw!D#9~?2af_y9dH^`= zq_DCQv@P3c;JbYZnwBM~OY=H$3AhFI(nfv-k_kG9xDULmQvJ}RO1gJ{AWK|$AYWnV z)B(i1|4_=KXrV<)m3)}=0my8Il6HkOFsq@Y@j8kz`WwY@9+uuQPVzf?Ic$K1URgR| zDqWtRwWm&<9TC(3L1)TH-`T#YjJQYvYPv6&i4ypya`aL&$&0D{xF`VPy(EOeg4=YX zNj8H;cT{qq`~EQ|=Tu%?F>(5=A7^wP-X2x-1gX*R}{1G$h~O^8As%pcvIbp6a|gs@weE6VFtzesU%2YXyT0$9Sr}YA{*LjRt?&A7RvihOj#3VG zI+nd#7OrT2x9qz+7q%=O|7OO!Wj8C@!=^)Wf=%xZg{zOgJM`U43+EOKzxC+5LpQ6B zhD{y!Oy=wZMu_nBFWC%<=~oY5IUFztydkuQ#9L>LU!0;{eCYDf%wz9c3+^UTa>!no z8M}Hgv1v# z_kNS>H$r|_Hgx_+sN_Mn@*(wB?lM;1HNcy_utX1{zvDslcRcRj%4v(lW@@}gMy0To z>x%M`C7K7MBCk$y$3%>GYf#+va;#2q*UPaw#a%DQ>J)dq97J)~DzV4Nl4EpKy&P`j z&{&66Hr*AzM>2AxXs9e})sc!EX%Cbm9XT@eb9ggBXUUQfQKpeh&@aa0}MWFm}6RA7M$wMLzkkX$+{r?OOKOPV-)sUQMOG_h*UYfQmYY{O-w@o~8mVdvn-0iueaq5x3uzI|D(xqD0RWeb(m}4bph$UxBq3V)PbgipISz>z~ zC62DEL=x9zPSbncHY#=$)>X1cELhOav3lUHB1C)4kT_u*RzeIpoDvWi-6-yi` z%(3zOI(_q=N-0c#Uy-g*pveHUPP7GDCFKEogrT!q`lURX#%*F$Rf6Oa32uMB-Uno|usK)p_P4NNE2*_+b+IpmS zKhsXY%6qICMK%lEk_Tx(3gE?DQk?f#_am`1=@;vhP`PB>^%snfoS!8SIf<-fcquonn*klP?- z_-#d9n~FGLx4a?ZYzT4cy8Y&ZoTc>6sE}?77wxaTm_DMBJrsRYww= zNNrZi^{y9tBF>_4X>-Kc9ORmB+fsuW<@4Nk9B(@2KE2SmnEu0@w{sSq!L@CfTbHJ`S2)0|w1E)JYB6TtB`*L$XFTR19)`!lLoD!q+5oZ&fOS1u!CK9+;{yi} zl&5JpzD_)(R+-hE4B!))C8x$BwJAvf+p4LP?kiVy3~0)=s+D-5evGZ;s#U~W0N1Ov zj#HNs*T?nNVD2uaepMPjq7f9(3Xa)FL=4tXNm^x)C zdXb>_Oas3Knb>!{fa0+8SR6CQzwkI_=9hN|>LX6vYR&h(F&x>rd7(bCu`%du404T# z4HUju8F6BUN1Vm;nTy8n+ar}b7W*QV553b8sc4Nj+MqcuF%3Fs+atK&DvTr|*|!T8 z3nP^~-!VoiS|YB!Am`cLGaG`YtotW5eF%Yc#G1AGqz1hiS{g{d5C%px)7(y@L#hUt zp;$J}*#PnP5EkRmd;dCl!3jHi1B2}cRUISru_4j8>n?e7l}q#>6QX#$1Mwm}qQ%uq zW_oUEyh~4^YxJ!oNAIj_{}bhHLf#YBJwflX=zeWd6k8 zNwb@=?_^%}JDET6chXqk7HeAVJDE>>((h!|8NJoM6RF9RkwYlkTL0WjxUZ)86{FeZ zp?*`lo;0y>JG*v0X_PIB>q)y}G-aWtRbp4I$*$8U?U#tJX_eSjYjWt+r2P`{HLVi6 zYE91gnq-wQ(iz5f>=}%?uupHr!6XSRiPXt#L0Ql_U^_r|gk!A#G;YB7MkHo?G~Go_ z8}6j#;DFj5;9uMWj)=ZDE-uu+@w+&C%63LlcTE>VHRJ1{HovIc<50TM9P zaexB^1qd-SEW8MCZ3X6t00)%Q8v}ETQQ~UqW516h+E4TVI`>W$KZ$Ra@m(Fr+dKgrKpg z^~6G(su8pUlh3536KG07e3qaY{w7{&F7H#5~ zo>xwy51m%&AyaCVV#h5#bW_Y62`-U?&Q7Bu1g+jc;wUyQA-%z%rb)t@tfHqeL8=GV zp3QBKplqAZrYc)S8-wOgC7-PMlI5#MJ_j_8sw_h*WhgbY;RBAly05ESJf7HngCRHo zCxPIE)T8awY{SafsMCzQeNH_cmECTiTa`l^2t17tiV}W;U*j;qKi&L3iz*d#gwjob z(tq9F6;khf)=tdUc-Q>{^)VhN?bcN{`f|E9DtaQu=;E zp1HU=`5gM3j4z*pzf>iSQkql(($eg5X-DD&cLL0)uu+(z_YHk%zEu!jsbpO7rmmD5 zN3ZHrsK0?0$XCiD4YBMSfU+$(Uy?8RgiAdtz7$_-19m`im_uKP|7w~MdjA1NXzpJ; zLhr<(K}38L9gU_|Gqz?tGyshnc~{2f6OHpHZ_$#bFB&3&e)|sp5BGn&6Px3|o_a>a zeaWbhUw;kzl9Z89_GINu0@A5EPm~p)o;gwpFntMZEhPtHjOl4j9GNlr* zp87CbvV2*pnpCGEtOl!NR4qg4>Rmm@mlYS1>vQ_DHFG2RM6#-_ntrNB6Dv8-m*>mD zzYJ}-FWm>qeYSl4=dS`NXd*&uv8yHG^-MZuFx5zR}S!81BSP z0J{h9z$_&{d;#jwVStk8(7UG+s-Yct1TQHBIwR>tvi!+xRsK4~!zj=yBZPm-l&-Uz z?2aA6g?255wF7)$M4c9t_Il{;09Kp;TQNdQDTO^lVNAI%)7wXYd1XGojiML;MzB}R zd2(c|{|qdkPL58*Y=alZnW?;(1FWWFxWqslQydy|G77qw&cc4cA{?0CPxkqt0GOqO zDoM%!qWehS=wQq_GInYhB(Pp2W9BDfiNYm`fG_xCP62O#na#lq3Z@Zrv0%SIkB`~K zJm>smbq_|zAwD7j@i_y zp6{A(TPP=!GeO(Kphm;I(GrxC>^0s=PQT8*=$Z!ScuFL3W4Ne3l2|`oaT_Mn(mwy# zYTN#p}xVG}Bvx#7jJ8E4d)8Fm&#(>F%aYZfe#^v3Y^_DEX$49rg?U#+=P6EM#; zg{yZ(igyLGcfar0b4LtzyzeN6p5wH#UnU#UvZXR@&Z~|qj@c$)S>{Mu$@{ia+?%A8 zeW=vBLJD*-%QI(sy(i+?63VQfK6^W7L*U%kvS+H$>=|n`Hy_4r(sQm?zn@+{vp<@% z@s<3!zIkgfr*5WNYN>1P$w>B=g}ssNrm$mM)ZxBbb){-{WNs(ylRXs4+`4cwlG*&e zgUsAyRKOS*_-G0ioQo$Tn;(9sELvC!CKP-5-6TV9(JxaCxf{jmQ_@gLZPHch@I)k|9B zIk&8NzwCqAv=W$5OD_85X(Noi&G?_o4VnZkxKlYNM$Y!sGEqH2=BGzAVOcV@kwq!8 zH^ZYnwLJq>N`hRLK*;8gi`y=g3sD|FnZO<7dqg9}VmjFpZ%?gginmvgDJq%T^T1hA z`DUeA53N7HY;0Ilz*=n=WUSC3sEP06dud#xw(nS@?zpU|U&*_T<(0?#K?iL88RNf| zFktJ*uNp4RMA)@z%cVZEEIMPh`+;+-hfTvtOb|WJl=WHqcvGLJji~?xdbKL`BpvXV zZ2yBZZi4D#7Yv zE;badQHC^5fH*k@46>;t7HXi6wUwsQV|dwR6ig;{8QL})4ChihMTB2UOwUJ5ddx3U zC87zSLILpg!WI*m0ph=hjIjS}VFuS3Zw4e4FCh@7Y)KH9A7w0;f`p=HTF`~_S&AN`0ySi1}GV&8~=PwlQ#gQEaG`8`=QQHiAgD>C#0$jM##6L&ezjq0se z&t5qj*#Bz#%k8(^WndNkz+L{&j4b{6@=eCBHjo+7TG$pQ0GGkT=sNgE=;wCyKbCXk zXzy|2S?O%qcerKmkygBPb+vjs9^pSkN~ZLDNEC|DX)OO3N@DA1o|*?Z5C`|BE1Rw- z-EfpcC#w^8knrBx2Wyx1@7llBvDkN``XMEPl2=}-!~t7Vsd5R&5N63>x7Nw~ga44F;25 z2B5&-0t##ex~{GP6_67R7s=b5f+R{ye?TA^%bOr_5cw0vZ8S!@EGjb*Ry~tLs2>|j zyz8FunzwO6sD^ZEmsa(-qx+DiCJ=@z4LvgBs(SMrcXl6+OKZ|2H2UPyu?d>>QuN4# zt?tu4rV?gYs|@Z6M@@qs!+{f zS5re%v}WXN&AEn}Gt4&G4iCe9VWON^%2X_OMfizbtd2s7X^X9ugsFW}Nv>fqpjz~Np<*{SU@o0OVwrJrU9 zoB3&~sBvFmk4vY*G+Q!y!}p^~w%+~$nXm!FmUimwr@*!b+%%ZgyqLe}4rUw(ISvN7 zgLgbd)0NTUQt+2B8-?V3;7)_JG+56)bcJjVI+J1LIw3dEa4W%cGXaL0OMs6i<|2t; zYz;_gQVwIUyYhIT>($3!etdoq0=LQgjnfA|1XIgnA!ivgclb;Pn6zA}Guy6>MjR!u z^2RxyIf@`I@fMeUgM)lp7`$|xo#dgzDMj-o?`#dH9C)8Qc(=fil)mIKSY0p!_atH1 zwj+d3cQCZP!+6J@8fbzTMNrS~CM_nmb$HlltjznuEU_J@FS*ucwv#q9x?rb!EQhi2 zE_nor;X#lX9?G7LWX#cmVePoiwlHPW(&u267M92djGSawZ6!`)EhGi&TGzm`mQH!} zOV_49nz}+N4K&3hA;hgo>=Sz^atWm7NP!(sRZ#s*lu9R;o+NFL43|m0S4tbeZ4oO? zeTOA)!eDYR#6h0yE|AskR<~AoSGG%qw|}dN+K)}i#2~Xa@II+P5Jbf?kG3Ce?>+u# zOGj7x6Ab$3XgLc0TN?;jexeY@a_&p<$fIp-?T@uS!spV=VvGD|D2x9&Jk<0ZD%VVu zDn!GKmIAvlp`mk=ebCD?MSvFn6jHF6H;0td1`s@8$2t9K&Xt_cpP20nTe5!QOpa#f zlfiD7O?1tj3ujl%a98bD>@ZU0g0bu2H-{IE-yQ+2NdRNQSv5BtH6H`cfZwKA}nFK zcL>dah!2)kJDDZb)pZ0-M;r={bJFzeOo)rXPp?fuWF+Z860_G60$21;>j{3J0H-M_ zydej%e6!bFEnmGM1bPoUlZ05c?}O>3=2K_~%$Kehk24MNoTO-7U9MLS1(SZMR_meW z3INy1x)*3hJ@{dT{#&Jy^lEsVq)_CN;SQyb3QVSMkJoYHvr>OL@nz#3%92HJlsKuT z@dU&}+$Y}oOr5mR$2slx*+Vm$xvlh_N$f1nc@v0aPY#eGw?gYYEP=+8TBrRAowOd} zoPNDheyAvL5<=!n_(XYKEU&GzG_F$ol#pX=n~76j_l`YX!|o4AiUJY~p1})!{SzY> z6-aC1^q^<(?BGZp=@{_vgQ7kt50pH?JR`ru0qs7Xt@SlbZM}z;RqYw@?Djwl!39s9 zXG{GyPlbO177GVFL*rYTDyu!`5Zeze1>+SE5Evb(Io&rhRO9G-y6<8Iu^&R8-pbZR51n!;Qhnby7;g@0QA@SwTLvI>|-P(;WS84jw4!GgVB;{}7#}LHt zVBzdtxYz0Es7#Alpq^>`V$9m-XXX?WnC@^`q)6Zg{iplTIXVVn=Dw4DK7i_DmZwhx z)`XzL$nZF<>W++!@iERnd}=ht0k3L~S?Cf6P@|AJk1|^(S&UHhmZlhYet7U{n2;P} zS5MFYPpZpfrqOYJFD2(_I!`#t>F1w{jP=he(B znX}gCHr%r3-LU7)r3CGHA$u`QJX#$yk3KUpT^Mz^u2x*BnB5XEzt9|bWUl@j&961j zw=AT+d2peBaZ9LpccftVqCe!=M-XaCp!~%SF!-ZvXX4duSGJL=fYX;x&+u2zUpYTJ z^xW^_nj)zgvyM!4yr%T>@%bM?}dOM&`Vn_q4YC6yp_@G=ZVx~}G3$$PFKXv$O$ zB_Q7E_uKnmdy0bsT7{ucChCicgm6l;de40x=T-CFsSL0 z69>a`uLz+S46|1-6^oNjgH4)zW-X?VbKKl+#HpyOOh($L#x0-*Sn-ztYJd%YcApW< zNXE7>_GU-7*XPh9Z_KT|Fx2SKJDv5;#GVoG=Gjz{-j172`QR47$xHr3aWYthh`zy=6f z)F!Dp8d_Ac&j!XU%uLAv7Sip3*NJr4RV1ghpw)QzmOy3dK2L_U0d=^hTD^l4lRQi{ zSAcE;Y9y#EBD==m$;si736H=};IH=J_^lD71tqQx1TwaX%Gwx5$J|tbmI5Vhog($A zgCE8G=eJ_#=5M2UQ~L$TX3*~;z=lvZ0qz;+$DRTg1~h7Vz{=nudXvama&pik6*}Ol zfSwG$XUYZ;N025ht=vgK(WIZKQhjJ8KQY`lB9sX|73T+eKWXXw6k2hQ9UqmM0)1+n z+VyADt|GLHX9OumJ14ABg?94v^E2epfgW=V@ndHNzJswirKug2IX@%r19apm;Gh7HVY7G%!Jz4~&sU zXzWSk@Qk-i!h z9$Pph8&m$kln$+Wx9qt$?71O(K7f+ke8`D1f*7NPxs#?VZ!=n$!;MRe!!I9>B$Y># za>Tdrrk#uXLz`M6NiDGQ4CapMeRrHmB;u%{mql|52t0cIcf&c206lhmX~$yy4|lx1 zWBTOnuiYtA4;!NL{vu0bK&j+NE zoIbnv%NJ(2Uw!CEoEf+}d}a8#+CWR#Q2-0jRBt%DHtehwf825w+;A3zH*CA*Y`*Di z{-whJDxEuHcHpJq7lvQ>6fpkc%4lWHcXHm$nRhNUFYf>0p|=k$?n3xMSSD(7_6xzqRo;`N?*erDR<;&zd2wMg?qCU)X@05jY?WCa( z0-T)V`Tp7R=SCu2?tSFHnSOx)D3sP3*!LpLgnI7oGZMXTKNttn0>eRjdC*k;n}?cW zR$S?hPfo-GPG80p5)JTk_^~0ym~)rB!2TtA1S?_h z1kdOO07vw!+a^4BJ$#pb-wzbY*B>7OPE?y-kii;U0_dTY3NN#=iLQ`Rrlob-(Cj#; zHD;>cF zCWTtLLO+eF-dR>78Avs$TB(~JEw4n&t@=G*vppt|J1`~5DK#Cg5-(eHM{~_G%|1(K zwoswfz5U&H$brveElHMSO4MA)P zEM@dw9rB1*2B~%$dySK(Npr7Ex&Y}XL65Wn@)!;gawrwrBijHp17y)pYg5u52APTR z1K5D6*`(2fApl#k!DFa0NH80nt@(yw=xHoK4fKyv>@*h`hK-eWGU|5xI5XhPKY=#< z8m4xS^Uonq*PA9fETKnx!cXj;P;A~ib|z+e`XmStf{-p_7F|Rx#nLnXHvK$69vRIM z%;zw(&^lLX>@F*Y>nW-PoC0SChIxJzc|orrOY0yqd<88L&`sJfg*~#JO8*Xdv|+`} zVBq9u5i5`vq=Q^Iz>@^&Gk%bsIKKH;k&x}0bkRR;_)uhv6wTB>5jJIOP1a|=p8uAA zq48T&I8K}2ZVn~x51U#g)Ain~k6(E_Y|3I+S!9+mjZVEV6eMs7q)GPq^H(o@=~AHK z^|ZOJZ#@3m<6qwpO4=OewnUTCu3mip;*2?JwKJ-A=1Y0MpBLzw+ZswKf8SaG?#JYu zJDM^Y=Sse@>9tLuub+AIOekr```k`&#NqsM8O&DFNIdiCb#q|fS8cNwU+;)yf@5@R z*whd;*`BSrTyx8mal@1m7=Vf`Q%2ZSAB95OOP4Rr;;t<_oB-*6YA&h&qwHw|3-S{ph5vi;hmK>ge>Xadhg|wC1s*K02)rcy#Kf z7mv<_6~53~<8JaLta5aIvOb!Dv+5n4)(1Q~b!*ogoie|~10J2aHxTPOI*odikkyXP zbJMyx_!sHi>_j)%`Og0V{bc7m{}R3aA$dcH z?iaht9<)&b0yf?&!^?uTjL^~^g8gIA(F+t`sLGep9O-+wq53RRA&4J0TBMH zGz8blBiMs~1#h?<85}&rgYHL~lo<^|IfdS(RP5~0LL&Uvs0=^FzK%CP-J%j*K_DzV zEC3{KZSVPSASFAKhA~d)@V|0^{b1+d|W$wyKw+KRLS zyt010{*P%15RybtN`f)}E_ne6tm82^!F~x)h#I1xa|*wW_x>Hr*kz*Id@!tB0|mQ_ z(WP~DIrqqA(A~eZyGgqsZaO#_l>lG|nl#!bIA!^t21leGmx2blF{^GYWTdBBz6}8E zU_J~Sgjt*Bm^|Cm=1Jo9WrAj&)?;m+r%%IB4``|57m0F7Hq|B7c_LY_ga0}f6o&o~ zniw-fV-OD}1YuD#v;hLEdqy7fOglc9htnAIL~9ST|x zNz-^R%%y{#buDf7(XZr2xV+D`1C+PxT-nhk$i65MU{;%Ngq#A5HVKz@IAvVk#JU8` zLAL-*v(1Y`A*!ppUUX(EYXyE=Vb5bborki05>Wdcn#B89%Rk0xfGazA^V||Wf{m^0 z87<$lWXA94!6WQ>r@C&*g5P%#5)!L4IOcCK;W%PodEx6b{XDwjm`N>Fj%p3;S@F=NQBRMVRMG^u)*pax5$T2vz_b2R~Sm&sV`B6@k07D#Wp5Vn>XS?q9Hz+|h~q;dqB~ z#4mwccJU22wTV)w&&77X5>~&m`?>VTNN)$A+h(=gL(ev;4c#B;j+hP(tJRaXLfv}# zG#dB3iIQvpcmuFv1qV!A8i6F$2*|g{z9cpR7<<4m$_S8}7WIb|OIv9Kyt-xMPCeO| zgz=GQDxf0$xh%J5qv2?dsvRl%Up{`+k%~acI9D$IK8153AM@z&m+jzJ!ZVCEC za+LHPk<^^(#Xn`P(l71r-w^(qD&wzdkQ8F#LAazA6d;f+f^eJe85qNjIO$Pf5*899 z$gbwsjrIy!4oEPOF6DKAO&FsjBc2{GijqOX&Hu8Y5#r-sLc>v@K}{u?w7~ zES1SBGCM(qD&TKLG?#$r7)Kui${EHcc^J?1lhrYH+x|OL$S!z(f?F64th!wn;Oe|M z$~!nlV8~pwiM7sd&ZHF<7kjODycU3 zS4zYG7o*I#Gjjr^w=&DGI7k~o>D<6K&b)RelwLo5hHz%$Yn&opgIoEvH}YW%uQqJ0 z1496D{Lc=C?RmIxpWPaG@_k#Sc;z2R3_DAs?v$&iubiH}6ml2Om~T7XkiBo7y%cs9 z-A>MpCf5iT6}M{l+`#{umY{ntL}^m?lPC>z5qy{e`%p^XMflJ_Gf}QM?>z8psj-jApdIqbNNwdo*>zV(m=_p)i0B7gIl)pyH$p)3S5b- zOkbcA={;A@v24qGrEP`BEcPF}%E{kqL(pGaoX0W}|2mnyXFHEoYN-sgW*BBeoBS$R zpLBg<0p@2BF+V%ues#FugV8mD5QL?S6Tu*?@!dEc`91JrZpDlj1D41R;Y&jU8s(Y-ECB^ z!3t$O>1pc41?ALL!3=hvWiXAwS14YEDatsZSH>f8wp-=2X5F+hjRR>dgZQf8473iS zg&G=)On(RNDfdLiJz?liPlSo!atZPUwCT{3`hbK8jRtd?v~+74=e%~vW@22(p**|S z%wWwwWo`_r*FT7z{lEtSdN01_g@vh~tVmpPUvvsTg^|c>$4XEoPlC zN>ImmqAyXEk|4JXDWCH6CMlM{73f;S6{zAv?f#6^cc>rCkxJ>lB!vRwAeJ=dy1%6g zRdJE_5QiCa$_;{&Ql2aNUo%-@z5qn{cNl-8GX6bU5;!Tw#f~1iN~!v$Nj|sMn%H=<>MNx~&Dly{ zFhd=;t}jFo4Rbz655X_Yb${09_F24!Lq>0=%u}k&XlY&RkAD{Kh2*qHYg8P{3AM6C zdCUzNXH)hJw)*r|RCbTFh~*NYw z7nsn$EU3tHNGUK&>M*B-GIq*o&P%-zOGt;>!`*UhmM^^<{J;$&6%A!1_Bnx0frQDyyjhJMPf%DbKJU z47=whhnYYUEWv2nI8|9wBcJALBuyGQTdTHm$6ukbNJOZtC8w5W7T-midX!!;eL^@7 zQOSFegI^*KU(YaAN`OPHC|T93E?fOBCL0)J0$3|113d9rKqnfLed6csBR=P;RKe2U z`LW^t!CKP41jTv(0nLCeH~|YGG;1W5DB&ch`|2B;Vs7cSu~&#rl7BOWmYciZuTQBnIJF3N&75M=j!L8S;LZ%N^6$}40?J}eCK}x7 zZGEJ*iyx)nP*Vm>pJx_SEW?Ub6REho@4R~^Z#TSx)cmD(_U=nm%&r`ASoS%FMq z6AzZ`SZoR9?0LtD__U+OW#}C|YMegwp({7g7;@E2x8CMbXB)#@A#t^(g8%w9mlZID z^BWgNL;1|GdP3UGgpDK^2R^Z2a^?K4u(kPD(S+pLwlJEVm~yQul(+$`*a=xT6N;h3 z;n}m7&tBXA(xKl!6x>*MYvcAC8@Io+Ex2)eXyf5f`jN2p=xs-CU}wlt4vh_oX~A?@ z+o?gns5f;BnTxC=yOfSdVQIUl?TFAey*`{(K5toQi|%fX)@=m_xToQlW>a?KFAXM3 z6YvUK^38-iRqLC>)`nlPBIb%hu2SlM2C!e^I~NVe7rlN2oO^fDGp6gJDXG)d!Y997 zzAI{T&rV?&D{5|VCDW}l&9l89a%r<|bItSK2)8-P2I_WU+*0hwE;O3?)mXaZbfO#9;SU!Dl=EM!Oy=3e3!C<2223cjI znHw$HEC&?U&}#u26t$;J*9oW;mZNM%6N^ParRd&bB{Vc%l71?+k3R*5PXAzSN8i~& zKQ_I=H4()YD-gwWR?EkRTw}pq@`CAQ>?t%1k+LH!iQ#xrG#5CY9HFOar_i8q*m(^S zR69-zD`ad-E`V<0Y|<~m{*nYs0?yOVVbSEULUxT4N?0*Rf+`0SvRpHVQ06o=zdbqZKd|coI=rzH@jGnQ9q`;~4^{1W9?V)U2t*ni^_LjX?65>X2K> zx;h3SFn*X(zDeeciMZ7aj|$BfvUn;c{g978dC@a5JPHqIF>1X)K(4=X%7Nm=6MAZs zTs9=u&JT|EQRk#s533KuzzD*WPXYm^CZ#t;?oB1~CTON4p?tp|7XcM2aMM%e@%oN? zl*Il@8ffatDGc$bAo5S&1Ms6fO1MlQv3g9Rg#Ob6VEXz0fYBC)+^vQAr@AG&zO3#^ zQtyN!Yt9e$*O5}=2`G6QK6M(12dXCvhPcOIHwXJVAC)c&1fjgMgA;vZTo4fOmryAl zbSVMVRW@lyjk#O+Qcokedw9d>Sm_`As_u#V3@_4>rZKs2v$$!suZ zLV=ul8_3eyI52XEaSt1{kzGqBQ~p7t7;iSW8y2Qe7~nNJ?%n*~zg(Q>P|9VRS|8 zT<`K91T^Cbm}!(s_G&CTXeEXe0^x&|sSw^ykk+V#jxNTyON*M+p+j)S=ul8{+~u)_ zO{k6vM`LK06Jar@ip;OV)&7#w%Z#uwhj2MZ%99!X7_$suXC$?9JhXy9ttUqt3s1TH z_%leR3OVAWULgce`=Ag6yY$>hh;6tu$#W&Dhl@eyqRniRD5 zg%neGd(-?8Eqft=S_Iu@cZAv-DSVQeLkZEG|23{T{Ld+Xr4TCP>7lNSlY*4*B4uWRaEyp^hr0bCc^{GY_vHPAyniC^ zXO#Ho$DtmqQ+zW#;qgZ3B55$txtUh`eI*n5Ib5_rsIk9zlz(hu)ZJhcbFQ zP2LcBZ&F3?(pxT-`~-PVl1JP!{HMsfO5QAa8RY#1C8p~SzLq>9f%6mOeUUsymSPmC zzo4H#ChrD$KOygL$opIJ{&(^iH7kz_eV9B(*J6aMKKglvyw8v)6Q=kd(9ds@w?G~v zb1`W`Ml4h4Uuo1xrj3A1qcY2KjK2YZ94NVfg!yg?XPPzp>5b_t_#(ZLEWbeQB369H z;wzB6*cQq*Q`*n?QuH9^c;upgV(@J1h2aTynzIc<;AgPy0^B`0GPsAoi{xmn!T(Ln z4Uis;#=BgGkz1}c7>j>yNczCw{=nd5|Lq?b67lj=L*Y*i*>@7trybFx6O&MJ8tO=n zCOD?KXj&${vX*4#1`TOTE=z$aXvkSgwdCTN2}%Q6n1}{gKqQKSLR11Jo3O9I*=M#! zLCR=}a`}P2D3=#F9_4ZZ2+I!)E~Pn=Ow-P#d_!8sbP}MejfFu&9_%zw$u>h;E*hGV z6EvhQ*|;oJleXj#pKgOCab}3B=!kN;0jToK3|ONeNM$ZLtwPddLvs1F>#h|S{Ggs0 zvpzO)MmOm!ci%G`Oxa8H^R8Qo1xo-_4j7ZfSiF7gN;7UDX}~SZ)fQv^av|Oh*m1DE8wWlP2Si<#CJ2ShVCeWTXG-%T^~< zou6hbSgzh++`N3yXf|ek>}n)ScJP+Rag(xpdDNI>Y*;RF87r4Jlp5QN%biBpZeC7? z{n}*@8Ms?IWHMMFhx)lg!KA7XS52fW_G3$ktCxRNhqxN?N7S|-N3Nv}+7wvIsEv$d zGwllE??d$ah!P*4zLnw+DDlMfVcDsYr=5YKmDkzK zwEg~bae)hply-NTPA_@R{c)cE`OkmH4I*aTU4$q$Pb1!9%aNIBGhx(K%0RQN- z0>?!;4;SIQoQFTjKPNXw#fZq>`iP#r4G{z0x|7D|Oc7HytvO=xauKVS zkJ!955&KTgBYItzc#qyI!Z$GA=;k~Z&hhwdVsU2gVZauz4!+eZz_&5q?kNIX>~X*^ zVQES|PQYcJa`+XVO88ZtYWOu?q(NP^EMFb-w|RFVrk>?)VD-9K?naio$F$Pz?Sp1^Hv!hSvIgYSl3Y+C4)t(XjI>A!Zc%B1% zlEJl}=K-H$aGmEg;4=)~<~a-a9E0mUqkzvdxZy>Y$Fui0IBu$l_Ipwz3xx!Uo5IUq$)NpK!D zbZE<1xDuETE(Ii3nwwSVQd)5#FdqrbPX1VMq2KXTdSpP!=GXO@*Gi?o0~=#EIi&?e2%G=*>r z%u7LFK1FTFcBiZT<)B|_qmSC{%a)uiEI1cbsGFyW+Q?jCqX7v$=pUU8T<`XyEiVUL zXOPb|335-W^=SKzNd59ca5A7pZ?ocDELC?%T9^yv7|>!lGCK=u-5?5vU4AJ54g-VC z1?PidV%&B#joNtZgex2fOm!S^Nr4%K(S!3djQA=qyMkfMrC_8xI0c3YPWorvE)Tjq z2=0;Q0#iYJ8e!M;g5;V*gLX1(ScO*tz-M88_6Cx={P;fRLN4$=K8YBqSOo8r1$ z;mg2I>2CHNU6X>u$&AFPZ(%;{TA1F1`0mgRx21!Zt^WD>g@~V}Jd5ArD0oB`C;ift ztef{;mGx7B5MBoGwf{y~)=dTHWOF2NJ>p|&ssh)EB=a*q78dePP0^3wlx&_~obz1{ zfPk`vKx9WR%C^hFDUiY!1}OqFOkhMEhh@X0e=+Qzy(k-jIu#{b=KR-vp@0-zm%;iX!sN)Mq0wK9LI6obbNF4c)3f)zi4^UX! z7a>s=mK(JZ0j1MGPnLBW5-bpwn>0xl!jVnW6i-SE;jqsifea*qkD$9q^!Xw;Kx-=y zqwh6@?^P~hHIoqa&7=H}YMAux&V_13t85MX=a9)q14i(j7t!e!h7=1>n1$;&EZf3? zIX`_(KH|`dh~%FSXZu#eY2_Qk6=rm5gVo+CC?nrLli87ty|Uvo|HzG>QSL=9!ej0v zc&8&e505cYU}L1{(E%12toP_629E(_p;6YIo}8Ja0Wv#Caw1@ikNhJSD{hSQ3VXkb zp%r0u+<6{@D27pw&Li%m!Bqb~RS(_=_sKd)57{6EFj&sZ;#qLVTO7V!1JS@A2~!PC za%*H^VK%(;61w&>hDwaIzB&IDbU9?BFDsoO1!SAgmz4nlpHFrGO}93Ls2;9iD1ONC zy3U8>#rrb!O7yc|j}XgEX30Y^M=;u9e$)gY%8h|gU23}#GRDorR~`?K)(QVZk6-`$ zOUhp{clIq_)`uaM0v!Uid3IXbjRavTx3yIo#7j2$d=SSG;A~THR(>&ji;*D8t(TN1 zt9GPIc0`Z=*7MRKgcWo^7D@h59ZS7=2ka#DbkYElNPFSQ`e_Ub5otf*4qiHdmqKrb zlys2N4Z(YfBAoD|+=rY_x91^w@$KxDM+Nch5#cj>{Qv;y#f>WA1wLpNA*ue-#n`4*w1tP zf0_S>xlR|)NkuT{@H9yu@4`M6poN& zpI`9#q+w*1o`)xw`yhQWCQXtYl!BKQF_a?#v4&C)@u}3OdeZ>HCGdWWdo1AV`Ou*9 zg_4>Q7BHv*0iYfKs09FV#a0r+qxTqg>YBN?jEqrboisng>Xk)|SmCAO$Recb=O8t@ zTyD4f#VjXZx&efr%E`peA-G4a41*6jJwL)fWPYqU!`^Y9^1fZJge%NV-l&Q0Au@)w2Z?svNq4f8+r$$Tx8f zK=~p!0x1#VF9@R=Ii_Y&6`;Z|^g0*SH*lxwmFAF~8_)&$w}hGR{vJL5`VgcXW2Coq zvf$n&^FHYUN(>VMt*)pd<;;ULue=_ThU8jIaeSl)xCdt!FnbCQxpR?=$ioJbU%wA* zlNHDR`17|LW8v?7@f%-ERkp1(->d9?x3c?Re*W(tiAedCmNp)h8p082aWW!{A^+qR zS&vb4Ch(TXkdQ7SnXI40%s(QT0Ea2xbgRpi6}~Di(iMa=7NKwY*Z4Xu*68;4>?P63 zbP{$RO{?c6hX6d}BnP8#;oL-s@5R)I?~Q#149oW>2H3AW znn=r@9NV78&*-yd8mEz8IeQAE9Ir?@jrZ$=6X%oVZAo*_N^8p8lN5ULP5RVdVn=pVf|!Y1mPoqE zMyL(p1u6VdH|q&yc!D(Qa%~u?x=2y(f{6zs)r;BQ+J_RJ*;`-DxA8-+ny-3DUc4+r zul2f<86CaPdLGjI$#0+LMnF{mC?>LQQ`?>!NHBm2qtuiQ&jivd&nR{MhDRNc8n`WT zlcZ(OsAj&UhS89xDc`1s=id`F?`6*zuh!+|`m;ExA!N1<>D*jMq(OL?AF1NFYe*xF zN!KsxLuO4WW;KtdUWZyo{=N6lptn?#-l9oYnvYkZMs6%uBI?Q0s!UChe>ZaD9jZz6 zQ`1Y(w8fydMJ-kRjnWO6jC5cevwX^a(T!Q2EcH~UGV*`QGR5(5f0n~En2NB*KJkp{ zG%0kNHk;J&E=;P_2UD)T4sB1N|2IBe8tyI3JItS|eOkLbdQJVgDcC2fFE@qbav~6Y zL=(ny3a2(;PA08xPS>$qo44Yce=H17ozK#R8>L}l!!x>VLjZnyU>xum_he@sz?U0s zcrsOfBHO@uOqjZwmxjm5%;(BlRW+7lvL-Xr@qQOG9iJNOa*-kvb`2ebQF;>A!mtar zlbPATlzT}WJbC{7k}!A@?);JtzaBA3ckwMjHilqWoR5TM6SMI77OtG_aL8to#C}Qg z-;fQ^)dKUd^D$c^+0SJQnIL^>9z{0-mP zBWH$XtAY_z#$+2aVM4Q#$k=D_heA|K5i8`#>60hUo*6!SQ8p;($@;k~u!_o7B@-Jb zI&9JsDv@5Hnsit;kPQpd)8RlwHY)EhENY-hc8)v6OjaUItZ7EPAO)t_j92<6$R8#t z+lpzg`Y6-iBBeS|n_0A_-$kmgQu6PCeo^iN17|M%x;5IoF6h6u#@_tgYoCi(+^W9UxaUseosDK|b=_7JZM)yte#fva zIu+Z#jw$uXeWPW0_g7x|R`6a$_nnIFHDmYv;;MVaE$W&ciru(%@?Oi}otD9L z#bDZga7`F`ud@Etxu}1+Wcf%I>*dIrSf;{@H=E;=-)oOo-wNJq9lFyxl&%^|7azJS z9)76jsv0r|PG|gD=c}Ff1m_*W89%<#pA?*H!mf3}a8D?`Bb3Ja?h2Jp&Sq!~f|UJu zR=BtHiXn*9G)1r9OVH=Zd)D+Zfka_QPO!&^TrXepki6Kj484+dC)v+DdPv6}Vn2r7 z+YpMRJJTdwc|trht7$|HY1J?bX+v}f5eh;u=);_&O{4b;c>@q)MQ!Yupfx(>h7*m5 z_7bf*aRLI~Zob=ifwdFlEuaRl>2GZ(7rZE$yKgRJEZ-LoM9Uxh(X}qQ2w;6&n ziwldljQ4Mz+bv=;l4}w0wQBKI+l=9-l}!=Mqof*ccvua#F$?DE_Fmoi_RVWj%Ys>; zT^TG2>Mh!$UNBh5>M0(xqI5^EE@T@sQ+;DLPf3>skHYpMw)Cm7&cax)ZbM&ZCm-3G z%CxD+o3xZhP2~l#ts7!1w6SC02`!HR>ugPKL%~$TeCmsv(5P|?8o?5a>D$(QQ-|)`RJ#S8{yF2Nx@Yo| zPW$aV!ArSVw@}z;1^iq<2~FEC0|$GKhqsN{m9M6NOLX8zomN(;)X(x`{bsqw`!=L% zV5wZaI&InGdp1qgSeR+*z8ARaNLnKIPwv>e0C0teoR5nn;Ii;A=4ulykAGT z`&LJ+?CS@j$JcF+oAz7RZ|iPfOttM#S`Q?}18fvqDxIBkvn64yV7iqB%Ow=7gel9U zYH$gHF->FZxNiS!=(2yQ4ng_#&JE>A^tCM+k%Y=#GG@z>Y!qBUb>tTW-O3`aTjt$M zR$3_T$=1Mr^eR6-s--0+vf|IXgY!PDn7$Nt@5&bYQC&Wguq=#Ss#Ml(-Aa?NB&D{h zsxSgsRXj+*7rE1DnrVUpcx8%&Dn8SamEFYN1d&!tZ zYpLW(luOm1JhC04Y`u8$>}Pz(&Yc}Oc>-2q+6*G$3+ANP;B^!+9+GvF(=&|YWh1RX zW7#3k^|D>5)2A%`v(<55L6DT7@@T>?y$ny*vtE`=3fe9yAhY&FO!{!EAwzm zo>QfNfiwxY@UQWa5RaOin1GwC%foM20N9FS#c7)>+O}R)66;JC)kizl&9>#SH)^9T z>!r?b1>(mNMd`Yox0};-1F4GL>C)Y+CF#=rtNwK9p=kGdMPS-&q`vp-$2fAxI2 zV(6X5bj2~uG9QbAZt$UnGn$g7y7=VE)gK*98G3$ZFeXh631`Z%i-EQA3n@b*16x;& ztLJ~REoC^AG3)JOwCw{MXDf+0V=sKW=B~9a>d(%xztI!B7QY&wOjIVzJ68H`U;T+G z<=l5y+>iOWZQC!4%VHPeb?NffyTxtMz`DITF`U@5(wMY%;ky*AKQoz^TVmVNmimM) zWop^%XR^edwz%=}o?mtTWISa$$Py(>cBU;mZ#z?_{n_6;(v}@7$5N(4+25UMOXtdq zpiK9ncaUs2V>dbsk2#~>@Z}Sjjyu{vC{r3V{_VQE)_P5Yl30x36XBJ%WO?uHV=3p6 zHSuV^wXY<463vP6WO?_>wUqPVU2zDd*&3iuG4i0a1fMQxylZVLD6)N}WJR~KCt2Qi zd;FdAe||aTJaJcij)>IEh?K0}nJ(XTx44I>)R@?ws9fQbR;&saQpuPywQHzEKQnqA zHB6^BL{EHR;)`B{tZtqE1&K5-UB%Qr!TW_*|_@^c5 z{^!?iPArjF%QI#}sp&CiFq*zR^9XAzjSuadqc>B>SxTbryau6;AS7&<2GIiGX@+uj z5ix77RhEHhO;R?IhVO%MA0H(46tLC9kEisc>3iJ4D*lk0;YsTuKQ@_R?+3LF89fDL zM7|q+O`y^O8Z6a^434Y?{|j>8&-r!!V!s0|p-lx^J%%)!LhVPN*OoSDL5BQ_;X?74 z4!;DpXT!AMxZr@Mq4)CRM^(cq3o#(1B^Odm+Q^tNrdQ_#ERE@jT;_sYRIJAkMhgTewoLLvDR6{V9WRolvwQLyhbnY75iyi#8WUk zF^*qnX(&EB&)yKPl%eyQfQRX+Wl;Rn$}o5>D8=#AGK`3SS{Y`q&Fk>Go?36*7QjQgRxYQEkrv?Ld4D`UpdY%ekP z&UzQ<8!TmdjI$TIYyMkQH4SLlP0Ebi(*%v{KFYG?F@Urv(_*0JLdt(n`iZA}%m%%r zf@u(yz4}nmn33unEAmunwF&T0c2=H^t$u23%~NA*pBh_N7z^8qxS58O#bcW`^~SWo zI{O7>Q`c)#gX?uqExSRR8uF~LESEO+3Hmf{9_zLg%B53(nboTPYgVf=LaS<4v?``c z5l{T%sZrARP`q@Lyzj$Pmb65 z3qo5q!xUD=>bNZwKN$B^)+5Casc5ig&jhKQ?76TZ6>C?AUiy8+7O00kyV;t%^v@8% z6vYlvqbU9{g|h7_MElkq(X6^CM6StITM**fFOW1$%e9z}WBPJ!KD3Q(r|EVU2+Fi;Krsb?D@p9hFg01si6{7XqXnf)@+2^>e3C@0w&z6*fZZ%in(afEai^pL99PX);b zy8?V&ubwP}SYpi1$u5W+Qi#2J#HuoIV}3pI^O#`?Tjn<)f6h|t1|w%@pdaZOF+MUX z=Puk!)$U8!_;khH^CUqkH;K9w^oMhK`nJxajiNk?Dc^wYwEnr^>Wp1| z<6!jo&rO!)7h=0(?eR8JQT4Po5%0zj>m~0zL zS`NKamNJd}Y>TWB6i!*oH_uv?GCdFV&1T4u`ld)M?O;ng5*W*j03epRfDLpWtW<(E zumC}9(yJeDhLBg;gBU;?4+hE)0dCsMEJ}Zh!lXZg2P;IL!?Vm?tO?5Zhf(@-%JgsG z$zsGG3d>fQI&yttBNK=EOVc+banU!et!n3pRG(b4dDl>!0h&{I7}?M!5 z@pWq@k+gaPNfTd6TK25gp))c@ktixYo1#1@x{+d_=$J6x|5S?RKDZ|+TF%I~Q4TCQ zHw5P?Ysgbp`U|4*e<1HK$xFaf*&8HOj4lSEQbgK{y_HxyQIU9tQE>y)4kj%JS0n3| z3Zmln4OC3Rj%YcsIzfzCNJiO+z3dRh64{s-Aa$dLr6wjP3Wov|&y>1p$q!{vg)VS<#HLY}uD*h3b?qsGe zN+5Q^JG1TgX>g^JEQ}V~KIukx$AQ-%}FxOViNk#&;|jAbnPIYsv0_OHSSH_TE}wpKOU zuG@{bVUrvBIa%uZU<2b<`^YBew2)2iSM_F{;a3%Uo#Am2yi5_Nvn*eXb;Qpnc$lgD zDSLZbXoopbFfWhAPR6e$8dLU`w9ujiebSUd;z&YD*>|Lc9ojORQugg>VY{|WA#rp? zNZC8nLT5gul;};_Thl^oKBXs7n((ZYrtDp5p-UTFf&z4E@B^T);@bCQxmOcSiAyWM zqB|{g=c_}o7BQv$pCqNf5V1`NNI?=2dZpya#`b7yC-gmu5)csECpywX2ewUMeZm=^ zPgi!QOSKw!@$q5^_48Rs%eV1;Xnn2`Nd@Q&w|u3M+uQ zmJ!>r0{%J7ec5?KJu6e08L$NzMabJ(h3bq~dJmHx|cq z@t(LpQI7q}DPwyE0)NK?V;N2uw8ds`ouLH!*erhT`SvSGM{~;9LP=UPM!iMEi4~pr z_kXA3tnM(;Zq;&RNMxpjY^QVR>W|O$=!OBLm-TFWxwHqcVk7@p`^wMJ*Fcsq`Wno% zQyE^|nW0w#hidS8@?*&1N8_&6jL?tY^o00YOv1fi(jE)L{vcR1yDF3vEEUq^Obz%V z>tI#iY+Ez*#AsKJskPfOPod>o;fF}SDiU-wc`{fznhL5?2hZ` z@WJi`9meE$-!5mbRdy6XIp|iP{O4HaC~JgfivfpCTSVmSGsbV$)sT*A0=%j7-lsf} z^AG5yll}%T=@;bv5}wj)>RC-&w$~I={5Qn21}S5}eRD-zpD6i#OJXWrxg%xnT$xFm z2a>`-p6%7o5|UTxh!z0PSj-aXL>y!p7?e|xV;?3V_X!B^Bf__`+KBKcaQcmWTEU`s zVpw^v1e9zTqJUFCNLzYXvh0 zyzs~3b%o0l*27A!{_)Ak2il7`yt_Ua3Y)@&H!hGGr^hREO1sh8=M`k2(B2; z0apT73g?6?gDZ!tfUAV7f~$tBfvbh9gWCpI57z+af@_3pf@_9rf!hw(3fBhL4%Y#< z1FjRU3$7c^4Yw0+7hDfqFI*p7KimM^Zn!;gd*SxM?T0%6H+UB3EH$5bZZkesICfwo zJ-Afr-$Hha8h+FjPMTD%?7%tBKFz^{Q(#iI7cMtWdX9RIJ?k*X zM59_1)+<$NX5Tp8aU4>8wG=nAw#j^# z%s0yXA(?NJdB4nGlKDxQpOO}Umh@S8GCw2pmzhOM!e&69|d*0ZasaNoux&c4X{ka8a8(!$gYoYR#2xc5K` zlXS)$Tz!?UpQ1vzyYG_uW?VT#ry-S692UKX!eia%#q(Voi zRjd{pXS8JOR3CO47OPN6nF>`@t59vd3b~q9XnVT~?dVpaoxLj5zek1k4XV)45nct4 z;l>CRevUttg^LKGVnV2h5XwS8C<_6hEChtI5D>~jK!~8|_76(AiiY^&-SX|PUcu%* z(fqa3ubz&z+$@hTCa(VejZ}3o4`DUn zma28jwwsfQ?caMTK9TG=aNk-HdnIjcPFl!fU~YY+6Rd3+PSCeu30pbV_1?CoJBI3L zAU1s8S|0Pq%fDaudv%GKRJA*0-AO8^>Gjj`lK7FEFMt1)@4m9qf4e-@uqS2Pn-=$K zW52NSLaL!JW$RCi{S|(B8Dr`+qZB|9VaANbFk5+>jO;=p38jsfVk+H4u0H&i=bXeSR*U z9n;jSfIitRJBkfuKZ&p{?${wa;%lfQcgM~_-ujS(w>-&S3L;39dq{*am4!}bYwd@d zUoVok=6Se1*~WxmF4^qx56)%NSk0dN&I?a&>f+JuLCy5AGoHDrt`bImZmNnk)lpkM zT!rYoISyuNa)xj`Vzfw&&%ZaF%;F*{k3lmv(T(ONg!!D$n$AvCscCWLW$x6f$D~zG zJ!X$ZQ;&e7R9c+H2~zplgEiqSRq33r$5xO|Kd~*BPCr2!Dtq#iCy!mtoqK1MZWx=I z)byh*DwKcYT)D?nq^%8`6LPE9$la=@9VL6qh9`g78VvE%O{}Bzw^{-abT3OdbWA$_dqhz z!}_a1nxjoR8gPLEUF{Q#v1zwkRJK|RedVC;m6 zyJ+04%@r!1AX^`MG%{ef8kT=!6KAoCB@7EqW5qBbbM}*U$%ip^mqEi0o^t($al2RU7AyY@FZ?YrJ4JZO?zYQk_~q3+>Nz#ryZMQV;cjz zxAvoo?45`kuB=tm54zcpwjkloKi(phLuw+##54gYWD-e*f&w&G%m$ykaPG`UrJB-l ze2DH@T`H&bc;${J*DaU5$8lepjDhU{P`y3nmBeWRY?3&R)Lh78%64?e#)8zWa21Rgtg zeE8_ObEkaAPo81xd(anYAqF>hUiSA6?8dgt*#Pc|pz9fk3L#{B~7lP(FN2kan*+IPxyEXBNlF!6KD5bKggl?UpUrrVdPS7T{ zs)3ZktgKH0RCcz)BFKg5c!{dls&7TV73ZM*N*6$EHq-oLeEl$#Tb=i;P48Np-oCbG z-Ggfy1k*jC{Eko_n}56ietlD7C{^DJ)mK;X0j@IZe_$@YXRf(pu1T5eaL~-=c=OzE zpNqCZvrXcX1V?YQb6v3C6Uy!gW%q=dJ3>vO|8`4Ks96*Cu!yQVLecw>Rk##7-sG^#x=!EWDR-4?mFYVkHb>9~%VqaVnS|3DwNtyq3|E>+#XCJfvcthgxQUBMX}Nw)4!*X>_DwO-crfsWVFwi}bR*lL8)nRpF$B!3&Dy}u2SrgCZv(F~oN7F4w*DD$m z{mG7fl>Y$o*ES_vhSD`dNwIQWth^^S-4UB^_5b1iAM9UqA4xSIedl7j`Q&<6AK}|f z_zpZMtxneUrAzywr>M#U_ni&5bcyGGSiH9P)cv-@D7fq>{{i-j9OFSLebGIUp?@XW zeK_5G_?^!6ikf8I&ec|2N2x!`qiag4k~ITq$3XNXmACKa+}p=)TYh{lRX?~U9?Ul& znCv{7Zan(V@t?M=iRV5%#&f3ak4AW1aeH(MrU;w!jiKoA`=Xhy5@~wZ-jwLa2Bf5| zW2JQE_{#32rT4Db_t1*u4{e;q`XQLsv>pBTQJAdZf3ahv>vXyPKbKoiZ#UDem&DjU zA1;+eBuqslPJV-+oQEatzeT|NB6&26d!MET?~`p1C!2R816`Rpy-3%!^Uoqql$u%aY6dM_{n~^1rS*h5kEuF?s*>d3qHa5%+Uk@r*yE64r zkpiYcK9z=14l{J zzOHzsQF}&gDi-L9l%p9Ppa)o%?#bu@fk*VV;xBa`i2CbDJIxK;U$?8f=fAlNvtvBB)E*zJ7dF{a)K*R=JHgglHe+^?6Q=p zCb)*uZ_m^cTt{i9GusHR=k(U)vzZ2hU7Wr)K9Xr9xQWx3#XJw232x!^HSwOzc7j_e z&5=wS!R`3&6Q!9Bf_HHGZSkp0C&68uzA9dl=_c4s>4!5r3Esu&E8~Vt55c{ZrXtfv za6hMSOtfSM2;R-FdAyrOZBp_j7ujyv!URc#zZMm}TZ5!9$dOF>{Du zFcBKrojJnOFEEV0JXz8E@EHA!S~JfhpfonHE;?c@tZ!(yK<_#}R9r$+7so-|+W7f( zu{w@xZ|dR!Yz-_ElAHr%tf@_M71S-CEPExgJCS``Lz1ih&|u_oF)+NxWpuIXV~677 zLczx-+)MX(FYboPyu@?Oed|^3^`^ED*$K(V7j@Vu_1J}tA&;xD@c-CEE76ZlSPFf7 mmWK%>b6DU++w#(yuKH)D(r@(t&hC_{24e~gU}6p9?EeGzl6w*W literal 0 HcmV?d00001 diff --git a/tools/bench/moshi_gguf_convert.py b/tools/bench/moshi_gguf_convert.py index 3060c479..0bac1ee3 100644 --- a/tools/bench/moshi_gguf_convert.py +++ b/tools/bench/moshi_gguf_convert.py @@ -13,9 +13,11 @@ - CRC-mangled tensor names restored to their canonical long names - for `lm`: the SentencePiece text tokenizer embedded as standard `tokenizer.ggml.*` keys so emel's generic vocab loader consumes it + - optionally for `lm`: selected Q4_K mat-vec weights rewritten to EMEL's + packed aarch64 CPU layout, exposed in GGUF as tensor dtype metadata -Tensor payload bytes are streamed through unchanged (same order, same -alignment, same relative offsets). +Tensor payload bytes are streamed through unchanged unless an explicit rewrite +option is selected. stdlib-only by design, matching tools/bench/whisper_normalize_model.py. """ @@ -26,6 +28,7 @@ import hashlib import json import math +import re import struct import zlib from dataclasses import dataclass @@ -45,9 +48,24 @@ # tensor dtype codes (ggml enumeration) GGML_DTYPE_F32 = 0 GGML_DTYPE_F16 = 1 +GGML_DTYPE_Q4_0 = 2 +GGML_DTYPE_Q4_1 = 3 +GGML_DTYPE_Q5_0 = 6 +GGML_DTYPE_Q5_1 = 7 GGML_DTYPE_Q8_0 = 8 +GGML_DTYPE_Q2_K = 10 +GGML_DTYPE_Q3_K = 11 +GGML_DTYPE_Q4_K = 12 +GGML_DTYPE_Q5_K = 13 +GGML_DTYPE_Q6_K = 14 +GGML_DTYPE_Q8_K = 15 +EMEL_DTYPE_Q4_K_X8_BL8 = 42 Q8_0_BLOCK = 32 Q8_0_BLOCK_BYTES = 34 # fp16 scale + 32 int8 +QK_K = 256 +Q4_K_BLOCK_BYTES = 144 +Q4_K_X8_ROWS = 8 +Q4_K_X8_BLOCK_BYTES = 1152 # weight classes safe to quantize in a mimi component: the transformer and # RVQ projections (uniform row length, k % 32 == 0, consumed as mat-vecs by @@ -130,6 +148,13 @@ class TensorInfo: offset: int +@dataclass(frozen=True) +class TensorPayloadPlan: + source: TensorInfo + mode: str + padding: int + + class Reader: def __init__(self, data: bytes) -> None: self.data = data @@ -326,10 +351,6 @@ def load_lm_config(path: Path) -> dict: raise ValueError( f"{path}: unsupported {key}={config[key]!r} " f"(only {SUPPORTED_LM_VALUES[key]!r} is supported)") - if config.get("depformer_weights_per_step_schedule"): - raise ValueError( - f"{path}: depformer_weights_per_step_schedule is not supported") - if config["dep_q"] > 0: dep_required = [ "depformer_dim", "depformer_num_heads", "depformer_num_layers", @@ -347,6 +368,24 @@ def load_lm_config(path: Path) -> dict: f"(only {SUPPORTED_LM_VALUES[key]!r} is supported)") if not config["depformer_multi_linear"]: raise ValueError(f"{path}: depformer_multi_linear=false is unsupported") + schedule = config.get("depformer_weights_per_step_schedule") + if schedule is not None: + if not isinstance(schedule, list): + raise ValueError( + f"{path}: depformer_weights_per_step_schedule must be a list") + if len(schedule) != config["dep_q"]: + raise ValueError( + f"{path}: depformer_weights_per_step_schedule has " + f"{len(schedule)} entries, expected dep_q={config['dep_q']}") + if not all(isinstance(value, int) for value in schedule): + raise ValueError( + f"{path}: depformer_weights_per_step_schedule must contain only " + "integers") + for index, value in enumerate(schedule): + if value < 0 or value >= config["dep_q"]: + raise ValueError( + f"{path}: depformer_weights_per_step_schedule[{index}]=" + f"{value} must be within [0, dep_q={config['dep_q']})") delays = config["delays"] if len(delays) != config["n_q"] + 1: @@ -393,9 +432,107 @@ def load_lm_config(path: Path) -> dict: raise ValueError( f"{path}: depformer_dim={config['depformer_dim']} is not divisible " f"by depformer_num_heads={config['depformer_num_heads']}") + normalize_lm_inference_config(config, path) return config +def normalize_lm_inference_config(config: dict, path: Path) -> None: + """Normalize explicit LMGen inference knobs into emitted GGUF metadata.""" + if not config.get("depformer_weights_per_step", False): + return + + inference = config.get("inference", {}) + + def get_value(key: str): + flat_key = f"inference_{key}" + if flat_key in config: + return config[flat_key] + return inference.get(key) + + inference_dep_q = get_value("dep_q") + if inference_dep_q is None: + raise ValueError( + f"{path}: depformer_weights_per_step=true requires " + "inference_dep_q metadata") + + prompt_tokens = get_value("prompt_tokens") + if prompt_tokens is None: + raise ValueError( + f"{path}: depformer_weights_per_step=true requires " + "inference_prompt_tokens metadata") + + pre_silence = get_value("pre_text_silence_frames") + if pre_silence is None: + raise ValueError( + f"{path}: depformer_weights_per_step=true requires " + "inference_pre_text_silence_frames metadata") + + post_silence = get_value("post_text_silence_frames") + if post_silence is None: + raise ValueError( + f"{path}: depformer_weights_per_step=true requires " + "inference_post_text_silence_frames metadata") + + if not isinstance(inference_dep_q, int): + raise ValueError(f"{path}: inference_dep_q must be an integer") + if inference_dep_q <= 0 or inference_dep_q > config["dep_q"]: + raise ValueError( + f"{path}: inference_dep_q={inference_dep_q} must be within " + f"[1, dep_q={config['dep_q']}]") + if not isinstance(pre_silence, int) or pre_silence < 0: + raise ValueError( + f"{path}: inference_pre_text_silence_frames must be a non-negative " + "integer") + if not isinstance(post_silence, int) or post_silence < 0: + raise ValueError( + f"{path}: inference_post_text_silence_frames must be a non-negative " + "integer") + if not isinstance(prompt_tokens, list): + raise ValueError(f"{path}: inference_prompt_tokens must be a list") + if len(prompt_tokens) != config["n_q"] + 1: + raise ValueError( + f"{path}: inference_prompt_tokens has {len(prompt_tokens)} entries, " + f"expected n_q+1 = {config['n_q'] + 1}") + if any(not isinstance(token, int) for token in prompt_tokens): + raise ValueError( + f"{path}: inference_prompt_tokens must contain only integers") + if not 0 <= prompt_tokens[0] < config["text_card"]: + raise ValueError( + f"{path}: inference_prompt_tokens[0]={prompt_tokens[0]} must be " + f"within [0, text_card={config['text_card']})") + for index, token in enumerate(prompt_tokens[1:], start=1): + if not 0 <= token < config["card"]: + raise ValueError( + f"{path}: inference_prompt_tokens[{index}]={token} must be within " + f"[0, card={config['card']})") + + config["inference_dep_q"] = inference_dep_q + config["inference_prompt_tokens"] = list(prompt_tokens) + config["inference_pre_text_silence_frames"] = pre_silence + config["inference_post_text_silence_frames"] = post_silence + + +def resolve_mimi_n_q(config_path: Path | None) -> int: + if config_path is None: + return 16 + config = json.loads(config_path.read_text(encoding="utf-8")) + if "n_q" not in config: + raise ValueError(f"{config_path}: mimi conversion config requires n_q") + if not isinstance(config["n_q"], int): + raise ValueError(f"{config_path}: n_q must be an integer") + if config.get("depformer_weights_per_step", False): + normalize_lm_inference_config(config, config_path) + return config["inference_dep_q"] + return config["n_q"] + + +def depformer_weight_count(config: dict) -> int: + schedule = config.get("depformer_weights_per_step_schedule") + if schedule: + return max(schedule) + 1 + return config["dep_q"] if config.get("depformer_multi_linear") else 1 + + def cross_check_lm(infos: list[TensorInfo], config: dict) -> None: dim = config["dim"] text_card = config["text_card"] @@ -443,8 +580,11 @@ def require_block(prefix: str, layer: int, with_gating: bool) -> None: f"{layer_count} layer tensors present)") require_block("lm.transformer", layer, with_gating=True) if config["dep_q"] > 0: - if count_prefixed(infos, "lm.depformer_in.") != config["dep_q"]: - raise ValueError("lm.depformer_in.* count does not match config dep_q") + expected_depformer_weights = depformer_weight_count(config) + if count_prefixed(infos, "lm.depformer_in.") != expected_depformer_weights: + raise ValueError( + "lm.depformer_in.* count does not match depformer weight count " + f"{expected_depformer_weights}") if count_prefixed(infos, "lm.linears.") != config["dep_q"]: raise ValueError("lm.linears.* count does not match config dep_q") # The C++ contract also requires the depformer text-embedding family for @@ -932,6 +1072,14 @@ def append_lm_kv(kv: KvWriter, config: dict) -> None: kv.boolean("moshi.lm.demux_second_stream", config.get("demux_second_stream", False)) kv.i32_array("moshi.lm.delays", list(config["delays"])) + if config.get("depformer_weights_per_step", False): + kv.u32("moshi.lm.inference.dep_q", config["inference_dep_q"]) + kv.u32("moshi.lm.inference.pre_text_silence_frames", + config["inference_pre_text_silence_frames"]) + kv.u32("moshi.lm.inference.post_text_silence_frames", + config["inference_post_text_silence_frames"]) + kv.i32_array("moshi.lm.inference.prompt_tokens", + list(config["inference_prompt_tokens"])) kv.u32("moshi.lm.extra_heads.num_heads", config.get("extra_heads_num_heads", 0)) if "model_type" in config: @@ -950,6 +1098,9 @@ def append_lm_kv(kv: KvWriter, config: dict) -> None: config["depformer_multi_linear"]) kv.boolean("moshi.lm.depformer.weights_per_step", config["depformer_weights_per_step"]) + if config.get("depformer_weights_per_step_schedule") is not None: + kv.i32_array("moshi.lm.depformer.weights_per_step_schedule", + list(config["depformer_weights_per_step_schedule"])) kv.u32("moshi.lm.depformer.low_rank_embeddings", config.get("depformer_low_rank_embeddings") or 0) @@ -995,11 +1146,196 @@ def tensor_data_bytes(info: TensorInfo) -> int: return elements * 4 if info.dtype == GGML_DTYPE_F16: return elements * 2 + if info.dtype == GGML_DTYPE_Q4_0: + return elements // 32 * 18 + if info.dtype == GGML_DTYPE_Q4_1: + return elements // 32 * 20 + if info.dtype == GGML_DTYPE_Q5_0: + return elements // 32 * 22 + if info.dtype == GGML_DTYPE_Q5_1: + return elements // 32 * 24 if info.dtype == GGML_DTYPE_Q8_0: return elements // Q8_0_BLOCK * Q8_0_BLOCK_BYTES + if info.dtype == GGML_DTYPE_Q2_K: + return elements // QK_K * 84 + if info.dtype == GGML_DTYPE_Q3_K: + return elements // QK_K * 110 + if info.dtype == GGML_DTYPE_Q4_K: + return elements // QK_K * Q4_K_BLOCK_BYTES + if info.dtype == GGML_DTYPE_Q5_K: + return elements // QK_K * 176 + if info.dtype == GGML_DTYPE_Q6_K: + return elements // QK_K * 210 + if info.dtype == GGML_DTYPE_Q8_K: + return elements // QK_K * 292 + if info.dtype == EMEL_DTYPE_Q4_K_X8_BL8: + if len(info.dims) < 2: + raise ValueError( + f"packed q4_k_x8_bl8 tensor {info.name!r} has dims {info.dims}") + cols, rows = info.dims[0], info.dims[1] + groups = (rows + Q4_K_X8_ROWS - 1) // Q4_K_X8_ROWS + return groups * (cols // QK_K) * Q4_K_X8_BLOCK_BYTES raise ValueError(f"unsupported dtype {info.dtype} for {info.name}") +def get_scale_min_k4(index: int, scales: bytes) -> tuple[int, int]: + if index < 4: + return scales[index] & 63, scales[index + 4] & 63 + scale = (scales[index + 4] & 0x0F) | ((scales[index - 4] >> 6) << 4) + minimum = (scales[index + 4] >> 4) | ((scales[index] >> 6) << 4) + return scale, minimum + + +def write_q4_kx8_scale_chunk(out: bytearray, base: int, scales: list[int], + mins: list[int]) -> None: + out[base + 0] = (scales[0] & 63) + ((scales[4] & 48) << 2) + out[base + 1] = (scales[1] & 63) + ((scales[5] & 48) << 2) + out[base + 2] = (scales[2] & 63) + ((scales[6] & 48) << 2) + out[base + 3] = (scales[3] & 63) + ((scales[7] & 48) << 2) + out[base + 4] = (mins[0] & 63) + ((mins[4] & 48) << 2) + out[base + 5] = (mins[1] & 63) + ((mins[5] & 48) << 2) + out[base + 6] = (mins[2] & 63) + ((mins[6] & 48) << 2) + out[base + 7] = (mins[3] & 63) + ((mins[7] & 48) << 2) + out[base + 8] = (scales[4] & 15) + ((mins[4] & 15) << 4) + out[base + 9] = (scales[5] & 15) + ((mins[5] & 15) << 4) + out[base + 10] = (scales[6] & 15) + ((mins[6] & 15) << 4) + out[base + 11] = (scales[7] & 15) + ((mins[7] & 15) << 4) + + +def pack_q4_k_rows_x8_bl8(raw: bytes, rows: int, cols: int) -> bytes: + if cols <= 0 or rows <= 0 or cols % QK_K != 0: + raise ValueError( + f"cannot pack q4_k matrix with rows={rows}, cols={cols}") + block_count = cols // QK_K + expected = rows * block_count * Q4_K_BLOCK_BYTES + if len(raw) != expected: + raise ValueError( + f"q4_k payload has {len(raw)} bytes, expected {expected}") + + zero_block = bytes(Q4_K_BLOCK_BYTES) + out = bytearray() + group_count = (rows + Q4_K_X8_ROWS - 1) // Q4_K_X8_ROWS + for group in range(group_count): + row_base = group * Q4_K_X8_ROWS + for block in range(block_count): + blocks: list[bytes] = [] + for lane in range(Q4_K_X8_ROWS): + logical_row = row_base + lane + if logical_row < rows: + offset = (logical_row * block_count + block) * Q4_K_BLOCK_BYTES + blocks.append(raw[offset:offset + Q4_K_BLOCK_BYTES]) + else: + blocks.append(zero_block) + + for lane in range(Q4_K_X8_ROWS): + out.extend(blocks[lane][0:2]) + for lane in range(Q4_K_X8_ROWS): + out.extend(blocks[lane][2:4]) + + packed_scales = bytearray(12 * Q4_K_X8_ROWS) + for scale_index in range(4): + scales: list[int] = [] + mins: list[int] = [] + for lane in range(Q4_K_X8_ROWS): + scales_bytes = blocks[lane][4:4 + 12] + scales.append(scales_bytes[scale_index] & 63) + mins.append(scales_bytes[scale_index + 4] & 63) + write_q4_kx8_scale_chunk(packed_scales, scale_index * 12, scales, + mins) + for scale_index in range(4): + scales = [] + mins = [] + for lane in range(Q4_K_X8_ROWS): + scales_bytes = blocks[lane][4:4 + 12] + scales.append(((scales_bytes[scale_index] & 192) >> 2) | + (scales_bytes[scale_index + 8] & 15)) + mins.append(((scales_bytes[scale_index + 4] & 192) >> 2) | + ((scales_bytes[scale_index + 8] & 240) >> 4)) + write_q4_kx8_scale_chunk(packed_scales, 48 + scale_index * 12, + scales, mins) + out.extend(packed_scales) + + packed_qs = bytearray((QK_K // 2) * Q4_K_X8_ROWS) + interleave = 8 + end = (QK_K * 4) // interleave + for index in range(end): + src_row = index % Q4_K_X8_ROWS + src_offset = (index // Q4_K_X8_ROWS) * interleave + dst_offset = index * interleave + qs = blocks[src_row][16:16 + QK_K // 2] + packed_qs[dst_offset:dst_offset + interleave] = \ + qs[src_offset:src_offset + interleave] + out.extend(packed_qs) + + return bytes(out) + + +LM_Q4_K_PACKABLE_PATTERNS = ( + re.compile(r"^lm\.text_linear\.weight$"), + re.compile(r"^lm\.depformer_in\.\d+\.weight$"), + re.compile(r"^lm\.linears\.\d+\.weight$"), + re.compile( + r"^lm\.transformer\.layers\.\d+\.self_attn\.in_proj_weight$"), + re.compile( + r"^lm\.transformer\.layers\.\d+\.self_attn\.in_projs\.0\.weight$"), + re.compile( + r"^lm\.transformer\.layers\.\d+\.self_attn\.out_projs\.0\.weight$"), + re.compile( + r"^lm\.transformer\.layers\.\d+\.gating\.linear_in\.weight$"), + re.compile( + r"^lm\.transformer\.layers\.\d+\.gating\.linear_out\.weight$"), + re.compile( + r"^lm\.depformer\.layers\.\d+\.self_attn\.in_proj_weight$"), + re.compile( + r"^lm\.depformer\.layers\.\d+\.self_attn\.in_projs\.\d+\.weight$"), + re.compile( + r"^lm\.depformer\.layers\.\d+\.self_attn\.out_projs\.\d+\.weight$"), + re.compile( + r"^lm\.depformer\.layers\.\d+\.gating\.\d+\.linear_in\.weight$"), + re.compile( + r"^lm\.depformer\.layers\.\d+\.gating\.\d+\.linear_out\.weight$"), +) + + +def is_lm_q4_k_packable(info: TensorInfo) -> bool: + return (info.dtype == GGML_DTYPE_Q4_K and len(info.dims) == 2 and + info.dims[0] % QK_K == 0 and info.dims[1] > 0 and + any(pattern.match(info.name) for pattern in + LM_Q4_K_PACKABLE_PATTERNS)) + + +def plan_lm_q4_k_packing( + infos: list[TensorInfo], + pack_lm_q4_k: str) -> tuple[list[TensorInfo], list[TensorPayloadPlan], int]: + if pack_lm_q4_k != "q4_k_x8_bl8": + raise ValueError(f"unsupported --pack-lm-q4-k type: {pack_lm_q4_k}") + + new_infos: list[TensorInfo] = [] + plans: list[TensorPayloadPlan] = [] + offset = 0 + packed = 0 + for info in infos: + dtype = info.dtype + mode = "raw" + if is_lm_q4_k_packable(info): + dtype = EMEL_DTYPE_Q4_K_X8_BL8 + mode = "q4_k_x8_bl8" + packed += 1 + new_info = TensorInfo( + name=info.name, dims=info.dims, dtype=dtype, offset=offset) + size = tensor_data_bytes(new_info) + offset += size + pad = (-offset) % GGUF_ALIGNMENT + offset += pad + new_infos.append(new_info) + plans.append(TensorPayloadPlan(source=info, mode=mode, padding=pad)) + + if packed == 0: + raise ValueError( + "--pack-lm-q4-k selected but no matching LM Q4_K tensors were found") + return new_infos, plans, packed + + def is_mimi_quantizable(info: TensorInfo) -> bool: # effective row length: conv1x1 projections store [1, in, out], linear # projections store [in, out]; blocks must not straddle rows. 1-D tensors @@ -1123,14 +1459,73 @@ def write_enriched(source: Path, output: Path, infos: list[TensorInfo], dst.write(chunk) +def copy_exact(src, dst, size: int) -> None: + remaining = size + while remaining > 0: + chunk = src.read(min(remaining, 8 * 1024 * 1024)) + if not chunk: + raise ValueError("unexpected EOF while copying GGUF tensor payload") + dst.write(chunk) + remaining -= len(chunk) + + +def write_rewritten_from_source(output: Path, infos: list[TensorInfo], + plans: list[TensorPayloadPlan], source: Path, + data_start: int, kv: KvWriter) -> None: + if len(infos) != len(plans): + raise ValueError("tensor payload plan count does not match tensor infos") + out = bytearray() + out.extend(GGUF_MAGIC) + out.extend(struct.pack(" dict: + quantize: str | None = None, + pack_lm_q4_k: str | None = None) -> dict: infos, data_start = read_raw_gguf(source) component = detect_component(infos) if quantize is not None and component != "mimi": raise ValueError("--quantize currently supports mimi components only") + if pack_lm_q4_k is not None and component != "lm": + raise ValueError("--pack-lm-q4-k supports lm components only") + if quantize is not None and pack_lm_q4_k is not None: + raise ValueError("--quantize and --pack-lm-q4-k are component-specific") kv = KvWriter() kv.string("general.architecture", "moshi") @@ -1143,7 +1538,7 @@ def convert(source: Path, output: Path, config_path: Path | None, if tokenizer_path is None: raise ValueError("--tokenizer is required for lm components") config = load_lm_config(config_path) - num_weights = config["dep_q"] if config.get("depformer_multi_linear") else 1 + num_weights = depformer_weight_count(config) candidates = transformer_layer_candidates( "lm.transformer.", config["num_layers"], 1) candidates += transformer_layer_candidates( @@ -1152,13 +1547,13 @@ def convert(source: Path, output: Path, config_path: Path | None, cross_check_lm(infos, config) append_lm_kv(kv, config) append_tokenizer_kv(kv, parse_sentencepiece_model(tokenizer_path)) + if pack_lm_q4_k is not None: + kv.string("moshi.lm.tensor_packing", pack_lm_q4_k) elif component == "mimi": preset = dict(MIMI_PRESET) if mimi_preset_path is not None: preset.update(json.loads(mimi_preset_path.read_text(encoding="utf-8"))) - n_q = 16 - if config_path is not None: - n_q = json.loads(config_path.read_text(encoding="utf-8"))["n_q"] + n_q = resolve_mimi_n_q(config_path) layers = preset["transformer_num_layers"] candidates = transformer_layer_candidates( "mimi.encoder_transformer.transformer.", layers, 1) @@ -1176,10 +1571,14 @@ def convert(source: Path, output: Path, config_path: Path | None, kv.string("moshi.voice.format", VOICE_FORMAT) quantized_count = 0 + packed_count = 0 if quantize is not None: infos, payloads, quantized_count = quantize_mimi_tensors( source, infos, data_start, quantize) write_rewritten(output, infos, payloads, kv) + elif pack_lm_q4_k is not None: + infos, plans, packed_count = plan_lm_q4_k_packing(infos, pack_lm_q4_k) + write_rewritten_from_source(output, infos, plans, source, data_start, kv) else: write_enriched(source, output, infos, data_start, kv) manifest = { @@ -1193,6 +1592,9 @@ def convert(source: Path, output: Path, config_path: Path | None, if quantize is not None: manifest["quantization"] = quantize manifest["quantized_tensors"] = quantized_count + if pack_lm_q4_k is not None: + manifest["lm_tensor_packing"] = pack_lm_q4_k + manifest["packed_tensors"] = packed_count return manifest @@ -1204,7 +1606,8 @@ def parse_args() -> argparse.Namespace: help="enriched emel moshi GGUF to write") parser.add_argument("--config", type=Path, default=None, help="moshi config JSON (personaplex-config.json); " - "required for lm components") + "required for lm components; optional for mimi " + "components to declare active inference n_q") parser.add_argument("--tokenizer", type=Path, default=None, help="SentencePiece .model file; required for lm " "components") @@ -1217,13 +1620,17 @@ def parse_args() -> argparse.Namespace: help="quantize the mimi projection weight classes " "(transformer + RVQ projections) to the given " "block format; requires numpy") + parser.add_argument("--pack-lm-q4-k", choices=("q4_k_x8_bl8",), + default=None, + help="rewrite selected LM Q4_K mat-vec/logit weights " + "to EMEL packed CPU tensor dtype metadata") return parser.parse_args() def main() -> int: args = parse_args() manifest = convert(args.source, args.output, args.config, args.tokenizer, - args.mimi_preset, args.quantize) + args.mimi_preset, args.quantize, args.pack_lm_q4_k) if args.manifest is not None: args.manifest.parent.mkdir(parents=True, exist_ok=True) args.manifest.write_text(json.dumps(manifest, indent=2) + "\n", diff --git a/tools/bench/moshi_make_tiny_fixture.py b/tools/bench/moshi_make_tiny_fixture.py index 75c0c70c..ea793cc8 100644 --- a/tools/bench/moshi_make_tiny_fixture.py +++ b/tools/bench/moshi_make_tiny_fixture.py @@ -8,7 +8,7 @@ exercises the loader-rejection path and the converter round-trip) - moshi-tiny-lm.gguf enriched LM fixture (via moshi_gguf_convert) - - mimi-tiny.gguf enriched Mimi codec fixture + - mimi-tiny.gguf enriched PersonaPlex-active Mimi codec fixture - moshi-tiny-voice.gguf enriched PersonaPlex voice-prompt fixture All payloads are deterministic (fixed LCG seed); regenerating the fixtures is @@ -58,6 +58,10 @@ "depformer_gating": "silu", "depformer_pos_emb": "none", "depformer_weights_per_step": True, + "inference_dep_q": 2, + "inference_prompt_tokens": [3, 4, 5, 6, 7], + "inference_pre_text_silence_frames": 1, + "inference_post_text_silence_frames": 1, "cross_attention": False, "model_type": "personaplex", "tokenizer_name": "moshi-tokenizer-tiny.model", @@ -212,6 +216,8 @@ def mimi_tensors(rng: Lcg, preset=TINY_MIMI_PRESET, tuple[str, tuple[int, ...], int, bytes]]: dim = preset["dim"] card = preset["card"] + # The raw synthetic cache carries the full tiny LM codebook count. The + # converter declares the active PersonaPlex inference count in GGUF metadata. n_q = TINY_CONFIG["n_q"] def t(name, *dims): diff --git a/tools/paritychecker/CMakeLists.txt b/tools/paritychecker/CMakeLists.txt index f76450ec..b7164021 100644 --- a/tools/paritychecker/CMakeLists.txt +++ b/tools/paritychecker/CMakeLists.txt @@ -76,11 +76,20 @@ function(emel_patch_reference_metadata_logging reference_source_dir) set(original_print " model.load_stats(ml);\n model.print_info();") set(patched_print " model.load_stats(ml);\n // EMEL parity disables reference metadata-only logging here; decode remains unchanged.") string(FIND "${llama_source}" "${patched_print}" print_patch_pos) + if(print_patch_pos EQUAL -1) + set(patched_print_arrow " model->load_stats(ml);\n // EMEL parity disables reference metadata-only logging here; decode remains unchanged.") + string(FIND "${llama_source}" "${patched_print_arrow}" print_patch_pos) + endif() if(print_patch_pos EQUAL -1) string(FIND "${llama_source}" "${original_print}" print_original_pos) if(print_original_pos EQUAL -1) - message(FATAL_ERROR - "Unable to patch reference model info logging in ${llama_path}") + set(original_print " model->load_stats(ml);\n model->print_info();") + set(patched_print " model->load_stats(ml);\n // EMEL parity disables reference metadata-only logging here; decode remains unchanged.") + string(FIND "${llama_source}" "${original_print}" print_original_pos) + if(print_original_pos EQUAL -1) + message(FATAL_ERROR + "Unable to patch reference model info logging in ${llama_path}") + endif() endif() string(REPLACE "${original_print}" "${patched_print}" llama_source "${llama_source}") file(WRITE "${llama_path}" "${llama_source}") diff --git a/tools/paritychecker/parity_engines.cpp b/tools/paritychecker/parity_engines.cpp index b1d6fb62..8db475f1 100644 --- a/tools/paritychecker/parity_engines.cpp +++ b/tools/paritychecker/parity_engines.cpp @@ -1014,6 +1014,8 @@ struct generation_load_state { emel::text::tokenizer::sm tokenizer = {}; emel::text::conditioner::sm conditioner = {}; emel::model::generation::contract generation_contract = {}; + emel::text::generator::matmul::lane_pool<7u, 128u, 1048576u> + parallel_matmul_lanes = {}; std::unique_ptr generator = {}; reference_backend reference = {}; generation_trace *emel_trace = nullptr; @@ -1095,8 +1097,8 @@ bool audit_has_native_quantized_tensor_type( const int32_t tensor_type = static_cast(dtype); for (const auto &stage : audit.stages) { if (stage.tensor_type == tensor_type && - stage.contract == - emel::model::generation::quantized_contract_kind::native_quantized) { + stage.contract == emel::model::generation::quantized_contract_kind:: + native_quantized) { return true; } } @@ -16204,8 +16206,8 @@ void dump_reference_decode_seam(generation_load_state &state) { const auto contract_name = emel::model::generation::quantized_contract_kind_name(stage.contract); const uint32_t supported = - stage.contract == - emel::model::generation::quantized_contract_kind::explicit_no_claim + stage.contract == emel::model::generation::quantized_contract_kind:: + explicit_no_claim ? 0u : 1u; std::fprintf( @@ -18930,7 +18932,7 @@ int run_generation_harness_contract( debug_audit)) { emel::model::generation::block_view debug_block{}; if (emel::model::generation::lookup_block_view(debug_execution, 0, - debug_block) == + debug_block) == emel::error::cast(emel::model::loader::error::none)) { const auto print_tensor_shape = [&](const char *label, From bd6f07b62672a636def570c1f7d8b24bd6f6f5ae Mon Sep 17 00:00:00 2001 From: gabewillen Date: Thu, 9 Jul 2026 17:13:29 -0500 Subject: [PATCH 02/61] fix: complete Moshi CPU speech parity --- .planning/.continue-here.md | 135 --------- .planning/HANDOFF.json | 70 ----- .../debug/moshi-personaplex-audio-parity.md | 106 ++++++- src/emel/kernel/aarch64/actions.hpp | 12 +- src/emel/kernel/detail.hpp | 8 +- .../generator/moshi/executor/actions.hpp | 282 ++++++++---------- .../generator/moshi/executor/context.hpp | 2 +- .../generator/moshi/executor/detail.hpp | 62 ++++ .../generator/moshi/executor/events.hpp | 4 +- .../generator/moshi/executor/guards.hpp | 105 ++++++- .../speech/generator/moshi/executor/sm.hpp | 82 +++-- tests/kernel/aarch64_tests.cpp | 112 +++++++ tests/kernel/lifecycle_tests.cpp | 52 ++++ .../generator/moshi_lifecycle_tests.cpp | 142 ++++++++- 14 files changed, 763 insertions(+), 411 deletions(-) delete mode 100644 .planning/.continue-here.md delete mode 100644 .planning/HANDOFF.json diff --git a/.planning/.continue-here.md b/.planning/.continue-here.md deleted file mode 100644 index 3bb58e2e..00000000 --- a/.planning/.continue-here.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -context: default -phase: persona-plex-moshi-cpu-audio-parity -task: 2 -total_tasks: 5 -status: in_progress -last_updated: 2026-07-09T18:25:29.229Z ---- - -# BLOCKING CONSTRAINTS - Read Before Anything Else - -> These constraints were discovered through failed E2E attempts. Acknowledge each one before proceeding. - -- [ ] CPU ONLY: run both PersonaPlex implementations on CPU; do not load or select Metal. -- [ ] REAL PERSONAPLEX: use the PersonaPlex Moshi LM and NATF0 voice, not a generic Moshi model. -- [ ] SAME INPUT AND SEED: use `build/moshi_e2e/say_input_24k.wav` and seed 1234 for both implementations. -- [ ] EXPLICIT CONTROL FLOW: runtime behavior choices belong in guards and transitions, not actions or detail helpers. -- [ ] NO HARDCODED MODEL POLICY: model-specific inference values belong in GGUF metadata or an injected configuration. -- [ ] AUDIBLE PROOF: do not call the goal complete until EMEL writes intelligible speech and the output WAV has been played. - -**Do not proceed until all boxes are checked.** - -## Critical Anti-Patterns - -| Pattern | Description | Severity | Prevention Mechanism | -|---------|-------------|----------|---------------------| -| Mathematically equivalent sampling shortcut | EMEL sorted raw logits and exponentiated only top-k values, while moshi.cpp materializes a full-card f32 GGML softmax first. The shortcut changed a near-tie seeded winner. | blocking | Add a reference-vector regression and implement the exact f32 sampling sequence before another full E2E. | -| Global sampling state | `std::srand`/`std::rand` is process-global, so executor instances are not isolated. | blocking | Replace it with actor-owned or injected reference-compatible RNG state without changing the seed-1234 draw sequence. | -| Partial run presented as audio proof | The latest EMEL CPU run stopped during voice prefill and wrote no WAV. | blocking | Require a completed output file, token/audio comparison, objective audio checks, and `afplay` before completion. | -| Model policy in scratch harness | The scratch E2E currently assigns temperatures/top-k/seed directly. | advisory | Put PersonaPlex defaults in converted GGUF metadata or expose a deliberate injected configuration; keep seed as a test parameter. | - - - -Branch: `feature/moshi-personaplex-e2e`. - -The worktree is committed as an intentionally partial WIP. The earliest deterministic mismatch is generated frame 0, audio codebook 2: - -- EMEL: `1049,488,572,1471,...` -- moshi.cpp: `1049,488,1632,1533,...` - -RNG draw counts align: 25 forced-text draws, then 250 draws per audio codebook. Codebooks 0 and 1 match. Codebook 2 logits are close, so this is a numerical sampling boundary rather than a wrong model or shifted RNG stream. - -The concrete arithmetic defect fixed immediately before this handoff was that `soft_max_row_ggml` had no arm64 NEON path and fell back to scalar `expf`. `src/emel/kernel/detail.hpp` now ports GGML's NEON `v_expf` polynomial and four-lane reduction order. `tests/kernel/lifecycle_tests.cpp` checks 16 exact f32 bit patterns obtained from the linked GGML CPU reference. The test first failed on 10 lanes and now passes 16/16. - -The Moshi sampler itself is still incomplete: it sorts raw logits, exponentiates only top-k values, and uses global `std::rand`. moshi.cpp instead scales all logits by inverse temperature, computes a full-card GGML f32 softmax, argsorts those probabilities, divides top-k probabilities by exponential draws, and takes argmax. - - - - - -Completed tasks: - -- Reproduced current CPU-only frame-0 divergence with rebuilt EMEL binary. -- Confirmed PersonaPlex model, voice, seed, and RNG draw counts align. -- Removed temporary generator/executor debug-phase public API and modeled depformer weight selection with explicit guards/transitions. -- Added the arm64 GGML softmax regression before the fix. -- Ported GGML's arm64 NEON `v_expf` and reduction order. -- Verified `kernel_soft_max_row_matches_ggml_arm64_neon_bits`: 16/16 assertions pass. -- Earlier speech-shard test run passed before the final softmax change. - - - - - -- Add a failing reference-vector test for the exact top-k exponential sampler. -- Replace raw-logit top-k sampling with full-card GGML-compatible f32 softmax probabilities. -- Replace process-global RNG state with an actor-owned or injected reference-compatible source while preserving seed-1234 Darwin `rand` draws. -- Move/expose PersonaPlex sampling policy through GGUF metadata or injected configuration; do not leave model policy hardcoded in the maintained harness. -- Rebuild the scratch E2E binary and rerun only until frame 0 to verify codebook-2 alignment. -- Complete CPU-only moshi.cpp and EMEL runs from the same `say` WAV. -- Compare token traces and WAVs quantitatively, confirm intelligible speech, and play the EMEL WAV with `afplay`. -- Run speech and kernel tests, domain-boundary checks, README symbolic-reference review, and scoped quality gates. - - - - - -- The fixed seed is 1234; keep it identical in both lanes. -- The maintained runtime must be EMEL-owned; moshi.cpp/GGML is reference-only. -- The earliest mismatch, not downstream WAV quality, drives debugging. -- The arm64 softmax fix belongs in the shared kernel numeric layer. -- Sampling validation and route selection must remain explicit state-machine behavior. - - - - - -- Technical: exact full-card sampling parity is not implemented yet. -- Technical: a complete EMEL CPU E2E is slow and no output WAV currently exists. -- Human action: none required to continue; the model artifacts and input WAV are already under `build/`. - - - -## Required Reading (in order) - -1. `.planning/debug/moshi-personaplex-audio-parity.md` - persistent evidence log. -2. `AGENTS.md` - actor, control-flow, test, and reference-lane constraints. -3. `docs/rules/sml.rules.md` - authoritative Stateforward.SML semantics. -4. `src/emel/speech/generator/moshi/executor/actions.hpp` - current sampler and graph arithmetic. -5. `src/emel/speech/generator/moshi/executor/guards.hpp` and `sm.hpp` - explicit route decisions. -6. `src/emel/kernel/detail.hpp` - newly fixed arm64 GGML softmax path. -7. `build/moshi_cpp_reference/src/src/moshi/utils/sampling.h` - reference sampling sequence. - -## Critical Anti-Patterns (do NOT repeat these) - -- Do not use Metal or Metal library paths in the reference lane. -- Do not substitute a generic Moshi model for PersonaPlex. -- Do not debug downstream Mimi audio before generated token parity is repaired. -- Do not hide sampling mode, clamp, validation, fallback, or RNG selection in actions/detail helpers. -- Do not interpret a partial prefill trace as completed speech generation. - -## Infrastructure State - -- No E2E, reference, server, build, or diagnostic process is intentionally left running. -- Current test build: `build/zig`, configured with `EMEL_TEST_SHARDS=kernel_and_graph,speech`. -- Passing focused test: - `build/zig/emel_tests_bin --test-case=kernel_soft_max_row_matches_ggml_arm64_neon_bits --no-skip`. -- Same input: `build/moshi_e2e/say_input_24k.wav`. -- EMEL models: `build/moshi_reference/mimi-e351c8d8-125-emel.gguf`, `model-q4_k-emel.gguf`, and `voices/NATF0-emel.gguf`. -- Reference binary: `build/moshi_cpp_reference/build/bin/personaplex -d CPU --threads 1`. -- Scratch E2E source/binary under `build/` is intentionally not a maintained repo entry. - - - -The strongest remaining hypothesis is no longer model execution. EMEL and moshi.cpp depformer logits are close at codebook 2, and the arm64 softmax implementation was proven numerically different. The shared softmax kernel is now fixed. The next narrow experiment is the sampler pipeline itself. Do not spend another full CPU run until a reference-vector sampling test passes and the first generated frame can be stopped/compared quickly. - - - - - -Start with: add a failing sampler regression that uses deterministic logits and seed 1234, then make EMEL follow moshi.cpp exactly: f32 inverse-temperature scaling, full-card `soft_max_row_ggml`, top-k over materialized probabilities, reference exponential draws, and f32 probability/divisor argmax. Keep RNG ownership injected or actor-local and keep every runtime behavior choice in guards/transitions. - -Handoff goal: make EMEL PersonaPlex Moshi generate real, intelligible speech end to end on CPU from the same macOS `say` WAV as moshi.cpp, with seed 1234 producing closely matching token/audio behavior, no hidden control flow, no hardcoded model inference policy, and an output WAV that is quantitatively checked and played for the user. - - diff --git a/.planning/HANDOFF.json b/.planning/HANDOFF.json deleted file mode 100644 index b0845335..00000000 --- a/.planning/HANDOFF.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "version": "1.0", - "timestamp": "2026-07-09T18:25:29.229Z", - "phase": null, - "phase_name": "PersonaPlex Moshi CPU audio parity", - "phase_dir": null, - "plan": 1, - "task": 2, - "total_tasks": 5, - "status": "paused", - "completed_tasks": [ - { - "id": 1, - "name": "Reproduce the first EMEL/reference divergence on current CPU-only binaries", - "status": "done", - "commit": "this WIP commit" - }, - { - "id": 2, - "name": "Fix the first proven numerical or sampling divergence without hidden control flow", - "status": "in_progress", - "progress": "Added and passed a bit-exact arm64 GGML NEON softmax regression; full-card GGML-compatible sampling and actor-owned RNG remain unfinished." - } - ], - "remaining_tasks": [ - { - "id": 3, - "name": "Run matched-seed moshi.cpp and EMEL PersonaPlex E2E from the same macOS say WAV", - "status": "not_started" - }, - { - "id": 4, - "name": "Compare token traces and generated WAVs, then confirm and play intelligible speech", - "status": "not_started" - }, - { - "id": 5, - "name": "Run scoped tests, domain checks, README sync, and quality gates", - "status": "not_started" - } - ], - "blockers": [ - { - "description": "EMEL still diverges from moshi.cpp at generated frame 0 audio codebook 2 because the sampler does not yet materialize the same full-card f32 softmax probability buffer before top-k exponential sampling.", - "type": "technical", - "workaround": "Continue from the passing arm64 softmax regression and port the reference sampling arithmetic before rerunning the slow CPU E2E." - } - ], - "human_actions_pending": [], - "decisions": [ - { - "decision": "Keep all reference and EMEL runs CPU-only.", - "rationale": "The user explicitly rejected Metal and requires CPU parity.", - "phase": null - }, - { - "decision": "Treat frame 0 codebook 2 as the earliest authoritative failure boundary.", - "rationale": "With seed 1234 and aligned draw counts, both implementations emit 1049,488 before EMEL chooses 572 and moshi.cpp chooses 1632.", - "phase": null - }, - { - "decision": "Port GGML's arm64 NEON v_expf arithmetic before changing model execution.", - "rationale": "The prior EMEL softmax used scalar expf on arm64 and differed from actual GGML output by 1-2 ULPs; the new regression now matches all 16 reference lanes bit-for-bit.", - "phase": null - } - ], - "uncommitted_files": [], - "next_action": "Replace Moshi sampling's raw-logit shortcut with the reference sequence: f32 inverse-temperature scaling, full-card soft_max_row_ggml, top-k on materialized probabilities, reference exponential draws, and f32 probability/divisor argmax; add a failing sampler regression first and keep behavior choices in guards/transitions.", - "context_notes": "The goal is incomplete. No EMEL output WAV has completed. A fresh CPU run reproduced the same codebook-2 mismatch and stopped during voice prefill at frame 10. The arm64 softmax regression passes, but the full sampling path, injected/model-owned inference configuration, actor-owned RNG, matched E2E run, audible verification, and final gates remain." -} diff --git a/.planning/debug/moshi-personaplex-audio-parity.md b/.planning/debug/moshi-personaplex-audio-parity.md index 72dc21f9..e30a7b67 100644 --- a/.planning/debug/moshi-personaplex-audio-parity.md +++ b/.planning/debug/moshi-personaplex-audio-parity.md @@ -1,5 +1,5 @@ --- -status: investigating +status: resolved trigger: "Make EMEL PersonaPlex Moshi generate real speech end to end from the same macOS say WAV input as moshi.cpp, with fixed-seed reference comparison showing closely matching audio/token behavior and an output WAV the user can hear. CPU only." created: 2026-07-09 updated: 2026-07-09 @@ -10,17 +10,23 @@ updated: 2026-07-09 ## Symptoms - expected: EMEL and moshi.cpp consume the same macOS `say` WAV with seed 1234 and produce closely matching PersonaPlex speech audio and token behavior on CPU. -- actual: moshi.cpp produces speech, while completed earlier EMEL attempts produced non-speech; the latest EMEL run reached generation frame 24 but was interrupted before writing a WAV. -- errors: no runtime error was reported; the incomplete run stopped without an output WAV. -- timeline: the current feature branch adds the EMEL Moshi generator and PersonaPlex model binding; parity has not yet been demonstrated. +- actual: both CPU lanes now complete, emit non-silent speech WAVs, and follow the same + 51-frame voice plus 12-frame prompt setup. Seeded codec tokens are not sample-identical + after small arithmetic differences reorder stochastic winners. +- errors: none in the completed EMEL or CPU-only reference run. +- timeline: implementation and E2E comparison are complete; scoped repository gates remain. - reproduction: run `build/emel_moshi_say_e2e_current` with the converted Mimi, Moshi LM, NATF0 voice, and `build/moshi_e2e/say_input_24k.wav` inputs. ## Current Focus -- hypothesis: EMEL diverges from moshi.cpp in depformer token generation after the first matching codebook token, before Mimi decoding. -- test: complete deterministic CPU traces for both implementations and compare the first generated frame codebook by codebook. -- expecting: the first mismatching codebook identifies the earliest model execution or sampling phase that needs correction. -- next_action: gather initial evidence +- hypothesis: resolved. The raw-logit shortcut, process-global RNG, Q4_K accumulation + grouping, and widened RMS square changed the seeded distribution path. +- test: focused arithmetic/actor regressions plus complete EMEL and Metal-free reference + runs from the same WAV and seed. +- expecting: matched phase counts and speech-turn behavior with close audio activity/level; + exact token identity is not expected once a stochastic winner differs. +- next_action: none for the runtime objective. The repository lint snapshot has unrelated + pre-existing drift and was not updated without user consent. - reasoning_checkpoint: - tdd_checkpoint: @@ -30,11 +36,87 @@ updated: 2026-07-09 observation: the latest EMEL log completed 51 voice-prefill frames, 12 prompt-prefill frames, and generated frames 0 through 24, but no WAV exists. implication: PersonaPlex setup and generation dispatch run on CPU; audible output and parity remain unproven. +- timestamp: 2026-07-09T19:10:00-05:00 + observation: the initial sampler regression failed on the raw-logit shortcut; after correcting the fixture to the exact `ggml_argsort_top_k` no-swap path, a pinned 2048-card case showed old token 1639 versus reference token 1582. + implication: full-card f32 softmax probability materialization is behaviorally significant under fixed-seed exponential sampling. + +- timestamp: 2026-07-09T19:30:00-05:00 + observation: Moshi sampling now runs through explicit projection, scale, softmax, full descending argsort/top-k, and exponential-selection states; the Park-Miller random state is executor-owned and seeded by initialization dependency injection. + implication: sampling no longer depends on process-global `rand`/`srand`, and forced text consumes the same reference sampling chain before publishing its forced token. + +- timestamp: 2026-07-09T19:40:00-05:00 + observation: `speech_moshi_executor_sampling*` passed 2 tests and 304 assertions, including a full-card token/state regression and two independent `process_event` executor actors backed by distinct model instances. + implication: the arithmetic fix and actor isolation are verified locally; frame-0 PersonaPlex parity remains the next evidence boundary. + +- timestamp: 2026-07-09T20:30:00-05:00 + observation: the AArch64 Q4_K dot product accumulated each block as one combined + expression, while GGML subtracts the minimum term and then adds the quantized dot term. + A 64-block regression failed before the fix and now matches exactly. + implication: temporal and depformer projections now preserve the reference f32 + accumulation order. + +- timestamp: 2026-07-09T20:50:00-05:00 + observation: EMEL widened each RMS input to double before squaring; GGML squares in f32 + and only widens the product for accumulation. A 4096-element bit regression failed + before the fix and now passes 4098 assertions. + implication: RMS normalization follows the pinned GGML operand order instead of a + mathematically equivalent but seed-sensitive rewrite. + +- timestamp: 2026-07-09T21:45:00-05:00 + observation: EMEL completed 46 input frames and 120 output frames, wrote a 24 kHz mono + s16 WAV lasting 9.600 s (peak 0.7645, RMS 0.05242), and `afplay` exited successfully. + implication: the maintained EMEL loader, generator, executor, sampler, Mimi encoder, + and Mimi decoder run end to end and produce audible non-silent output. + +- timestamp: 2026-07-09T22:05:00-05:00 + observation: a separately built GGML 0.10.2 reference lane had Metal, CUDA, Vulkan, + and OpenCL disabled; its device list contained only BLAS and CPU. It completed 125 + frames and wrote a 10.000 s WAV from the same input, seed, model, and voice. + implication: the reference evidence is CPU-only rather than a CPU-selected run that + still initializes Metal. + +- timestamp: 2026-07-09T22:15:00-05:00 + observation: EMEL/reference duration is 9.6/10.0 s, RMS differs by 0.87 dB, + active-frame ratio is 43.3%/41.6%, and the best 80 ms log-energy-envelope correlation + is 0.521 at a one-frame lag. The early live text pattern includes the same + `0,2769,261` burst at steps 10-12; stochastic codec tokens and waveform samples diverge. + implication: turn timing, activity, level, and early text behavior closely match, while + results must not be represented as bit-exact token or waveform parity. + +- timestamp: 2026-07-09T22:55:00-05:00 + observation: the changed-file quality gate passed the Zig build, Moshi LM benchmark + (701333 ns/op), speech and kernel/graph tests, 90.2% changed-line coverage, 53.1% + changed-branch coverage, live GGML CPU kernel parity, and cross-process determinism. + `lint_snapshot` reported only unrelated pre-existing formatter drift; all task-owned + files were removed from that delta after changed-hunk formatting. + implication: implementation-specific gates are green. The global lint snapshot was + intentionally not updated because project policy requires explicit user consent. + ## Eliminated +- hypothesis: the Moshi reference swaps the first two top-k indices before drawing exponentials. + evidence: `moshi_sample_top_k` calls `ggml_argsort_top_k`, which is a full descending argsort plus a view; the swap exists only in the separate `GGML_OP_TOP_K` CPU kernel. + conclusion: preserve descending argsort order without the `GGML_OP_TOP_K` swap. + +- hypothesis: PersonaPlex depformer requires RoPE. + evidence: the converted model and source config carry `moshi.lm.depformer.pos_emb = + "none"`; the reference tensor diagnostic labeled `REF_DEP_Q_ROPE` is the unrotated Q + tensor for this model. + conclusion: RoPE remains a kernel primitive selected by model metadata; no PersonaPlex + depformer RoPE actor or hardcoded route was added. + ## Resolution -- root_cause: -- fix: -- verification: -- files_changed: +- root_cause: reference-sensitive sampling and numeric operand order differed at four + boundaries: raw-logit top-k, process-global RNG state, Q4_K block accumulation, and RMS + square widening. +- fix: materialize full-card f32 probabilities, use actor-owned Park-Miller state, model + sampling phases and seed/top-k choices as explicit guarded transitions, and preserve + GGML Q4_K/RMS arithmetic order. Runtime sampling parameters remain injected; model + positional/prompt/voice/delay policy remains GGUF-derived. +- verification: complete EMEL and CPU-only reference WAVs, successful `afplay` of both, + focused sampler/RNG/statechart/Q4_K/RMS/generation regressions, quantitative A/B + metrics, scoped benchmark, coverage, kernel parity, and determinism. The only global + gate exception is unrelated lint snapshot drift documented above. +- files_changed: kernel Q4_K/RMS numeric paths, Moshi executor sampling states/actions/ + guards/events/context/detail, focused tests, and this evidence log. diff --git a/src/emel/kernel/aarch64/actions.hpp b/src/emel/kernel/aarch64/actions.hpp index 7b439cf9..98a57788 100644 --- a/src/emel/kernel/aarch64/actions.hpp +++ b/src/emel/kernel/aarch64/actions.hpp @@ -2748,11 +2748,11 @@ inline int32_t q4_k_min_sum_neon(const uint8_t *mins, } #endif -inline float dot_q4_k_q8_k_block_neon( +inline void accumulate_q4_k_q8_k_block_neon( const ::emel::kernel::detail::quant::block_q4_k &lhs, - const ::emel::kernel::detail::quant::block_q8_k &rhs) noexcept { + const ::emel::kernel::detail::quant::block_q8_k &rhs, float &sum) noexcept { #if !defined(__ARM_FEATURE_DOTPROD) - return ::emel::kernel::detail::dot_q4_k_q8_k_block_scalar(lhs, rhs); + sum += ::emel::kernel::detail::dot_q4_k_q8_k_block_scalar(lhs, rhs); #else uint32_t decoded_words[4] = {}; decode_q4_k_scales_words(lhs, decoded_words); @@ -2800,8 +2800,8 @@ inline float dot_q4_k_q8_k_block_neon( const float d = ::emel::kernel::detail::quant::fp16_to_fp32(lhs.d) * rhs.d; const float dmin = ::emel::kernel::detail::quant::fp16_to_fp32(lhs.dmin) * rhs.d; - return d * static_cast(low_sum + high_sum) - - dmin * static_cast(min_sum); + sum -= dmin * static_cast(min_sum); + sum += d * static_cast(low_sum + high_sum); #endif } @@ -2815,7 +2815,7 @@ dot_q4_k_q8_k_row_neon(const ::emel::kernel::detail::quant::block_q4_k *lhs, #else float sum = 0.0f; for (uint64_t block = 0; block < block_count; ++block) { - sum += dot_q4_k_q8_k_block_neon(lhs[block], rhs[block]); + accumulate_q4_k_q8_k_block_neon(lhs[block], rhs[block], sum); } return sum; #endif diff --git a/src/emel/kernel/detail.hpp b/src/emel/kernel/detail.hpp index a6238bbe..c23fb7c5 100644 --- a/src/emel/kernel/detail.hpp +++ b/src/emel/kernel/detail.hpp @@ -4585,12 +4585,10 @@ inline bool run_rms_norm(const request_type &request) noexcept { for (uint64_t i0 = 0; i0 < cols; ++i0) { float value = 0.0f; std::memcpy(&value, src_row + i0 * src_nb0, sizeof(value)); - sum += static_cast(value) * static_cast(value); + sum += static_cast(value * value); } - const float scale = - 1.0f / - std::sqrt(static_cast(sum / static_cast(cols)) + - eps); + const float mean = static_cast(sum / static_cast(cols)); + const float scale = 1.0f / std::sqrt(mean + eps); for (uint64_t i0 = 0; i0 < cols; ++i0) { float value = 0.0f; std::memcpy(&value, src_row + i0 * src_nb0, sizeof(value)); diff --git a/src/emel/speech/generator/moshi/executor/actions.hpp b/src/emel/speech/generator/moshi/executor/actions.hpp index 78b628a9..6b61b8df 100644 --- a/src/emel/speech/generator/moshi/executor/actions.hpp +++ b/src/emel/speech/generator/moshi/executor/actions.hpp @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -21,99 +20,6 @@ inline emel::error::type to_error(const error value) noexcept { } // namespace detail_ns -namespace sampling_ns { - -inline int32_t bounded_top_k(const int32_t requested, - const int32_t card) noexcept { - int32_t top_k = requested; - if (top_k > card) { - top_k = card; - } - if (top_k < 0) { - top_k = 0; - } - return top_k; -} - -inline void reset_top_k(event::step_ctx &ctx, const int32_t top_k) noexcept { - for (int32_t slot = 0; slot < top_k; ++slot) { - ctx.top_scores[static_cast(slot)] = - -std::numeric_limits::infinity(); - ctx.top_indices[static_cast(slot)] = -1; - } -} - -inline void insert_top_k(event::step_ctx &ctx, const int32_t top_k, - const int32_t index, const float score) noexcept { - for (int32_t slot = 0; slot < top_k; ++slot) { - if (score > ctx.top_scores[static_cast(slot)]) { - for (int32_t move = top_k - 1; move > slot; --move) { - ctx.top_scores[static_cast(move)] = - ctx.top_scores[static_cast(move - 1)]; - ctx.top_indices[static_cast(move)] = - ctx.top_indices[static_cast(move - 1)]; - } - ctx.top_scores[static_cast(slot)] = score; - ctx.top_indices[static_cast(slot)] = index; - return; - } - } -} - -inline bool -consume_reference_random_draws(const int32_t card, - const int32_t requested_top_k) noexcept { - const int32_t top_k = bounded_top_k(requested_top_k, card); - if (card <= 0 || top_k <= 0 || - static_cast(top_k) > detail::k_max_sampling_top_k) { - return false; - } - for (int32_t index = 0; index < top_k; ++index) { - (void)std::rand(); - } - return true; -} - -inline bool sample_top_k_exponential(event::step_ctx &ctx, const int32_t card, - const int32_t requested_top_k, - const float temperature) noexcept { - const int32_t top_k = bounded_top_k(requested_top_k, card); - if (card <= 0 || temperature <= 0.0f || top_k <= 0 || - static_cast(card) > detail::k_max_sampling_card || - static_cast(top_k) > detail::k_max_sampling_top_k) { - ctx.best_index = -1; - ctx.best_score = 0.0f; - return false; - } - - reset_top_k(ctx, top_k); - for (int32_t index = 0; index < card; ++index) { - insert_top_k(ctx, top_k, index, ctx.logits[static_cast(index)]); - } - - const float max_score = ctx.top_scores[0]; - float best_q = -std::numeric_limits::infinity(); - int32_t best_index = -1; - for (int32_t slot = 0; slot < top_k; ++slot) { - const float uniform = - static_cast(std::rand()) / static_cast(RAND_MAX); - const float exponential = -std::log(uniform); - const float weight = std::exp( - (ctx.top_scores[static_cast(slot)] - max_score) / temperature); - const float q = weight / exponential; - if (q > best_q) { - best_q = q; - best_index = ctx.top_indices[static_cast(slot)]; - } - } - - ctx.best_index = best_index; - ctx.best_score = best_q; - return best_index >= 0; -} - -} // namespace sampling_ns - struct effect_bind_contract { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { @@ -132,15 +38,53 @@ struct effect_bind_contract { runtime_ev.request.sampling_audio_temperature; ctx.sampling.text_temperature = runtime_ev.request.sampling_text_temperature; - ctx.sampling.audio_top_k = runtime_ev.request.sampling_audio_top_k; - ctx.sampling.text_top_k = runtime_ev.request.sampling_text_top_k; - ctx.sampling.seed = runtime_ev.request.sampling_seed; - std::srand(static_cast(ctx.sampling.seed)); (void)emel::model::moshi::detail::build_execution_contract( runtime_ev.request.model, ctx.session.contract); } }; +struct effect_bind_nonzero_sampling_seed { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.sampling.random_state = runtime_ev.request.sampling_seed; + } +}; + +struct effect_bind_zero_sampling_seed { + void operator()(const event::initialize_run &, context &ctx) const noexcept { + constexpr uint32_t zero_seed_state = 123459876u; + ctx.sampling.random_state = zero_seed_state; + } +}; + +struct effect_bind_requested_text_sampling_top_k { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.sampling.text_top_k = runtime_ev.request.sampling_text_top_k; + } +}; + +struct effect_bind_full_card_text_sampling_top_k { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.sampling.text_top_k = runtime_ev.request.model.moshi_lm.text_card; + } +}; + +struct effect_bind_requested_audio_sampling_top_k { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.sampling.audio_top_k = runtime_ev.request.sampling_audio_top_k; + } +}; + +struct effect_bind_full_card_audio_sampling_top_k { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.sampling.audio_top_k = runtime_ev.request.model.moshi_lm.card; + } +}; + struct effect_mark_bind_failed { void operator()(const event::initialize_run &runtime_ev, context &) const noexcept { @@ -615,13 +559,12 @@ struct effect_run_temporal_layer_attention { layer_offset + static_cast(physical) * static_cast(hidden_dim) + static_cast(head_offset + dim); - sum += - static_cast( - emel::kernel::detail::bf16_to_fp32( - view.value_cache[value_index]) * - emel::kernel::detail::bf16_to_fp32( - runtime_ev.ctx.attention_weights_bf16[static_cast( - physical)])); + sum += static_cast( + emel::kernel::detail::bf16_to_fp32( + view.value_cache[value_index]) * + emel::kernel::detail::bf16_to_fp32( + runtime_ev.ctx + .attention_weights_bf16[static_cast(physical)])); } attention_head[dim] = static_cast(sum); } @@ -1002,38 +945,48 @@ struct effect_compute_text_token_logits { } }; -struct effect_sample_text_token { +struct effect_scale_text_sampling_logits { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - runtime_ev.ctx.text_sampling_ok = sampling_ns::sample_top_k_exponential( - runtime_ev.ctx, ctx.session.text_card, ctx.sampling.text_top_k, - ctx.sampling.text_temperature); - runtime_ev.ctx.text_logits_ok = runtime_ev.ctx.text_sampling_ok; - runtime_ev.request.text_token_out = runtime_ev.ctx.best_index; + detail::scale_sampling_logits(runtime_ev.ctx.logits, ctx.session.text_card, + ctx.sampling.text_temperature); } }; -struct effect_consume_forced_text_sampling { +struct effect_compute_text_sampling_probabilities { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const int32_t hidden_dim = ctx.session.hidden_dim; - const int32_t text_card = ctx.session.text_card; - runtime_ev.ctx.text_logits_ok = false; - runtime_ev.ctx.best_index = -1; - runtime_ev.ctx.best_score = 0.0f; - emel::kernel::event::op_mul_mat logits_ev{ - .src0 = runtime_ev.ctx.projection_view, - .src1 = detail::make_f32_src(runtime_ev.ctx.normalized.data(), 1u, - static_cast(hidden_dim)), - .dst = detail::make_f32_dst(runtime_ev.ctx.logits.data(), 1u, - static_cast(text_card)), - }; - runtime_ev.ctx.text_logits_ok = ctx.kernel.process_event(logits_ev); - runtime_ev.ctx.text_sampling_ok = sampling_ns::sample_top_k_exponential( - runtime_ev.ctx, ctx.session.text_card, ctx.sampling.text_top_k, - ctx.sampling.text_temperature); - runtime_ev.ctx.text_logits_ok = - runtime_ev.ctx.text_logits_ok && runtime_ev.ctx.text_sampling_ok; + detail::compute_sampling_probabilities(runtime_ev.ctx.logits, + ctx.session.text_card); + } +}; + +struct effect_compute_text_sampling_top_k { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + detail::compute_sampling_top_k( + runtime_ev.ctx.logits, runtime_ev.ctx.sampling_indices, + runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, + ctx.session.text_card, ctx.sampling.text_top_k); + } +}; + +struct effect_select_text_sampling_token { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + detail::compute_sampling_exponential_argmax( + runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, + ctx.session.text_card, ctx.sampling.text_top_k, + ctx.sampling.random_state, runtime_ev.ctx.best_index, + runtime_ev.ctx.best_score); + runtime_ev.ctx.text_sampling_ok = true; + runtime_ev.ctx.text_logits_ok = true; + } +}; + +struct effect_publish_sampled_text_token { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + runtime_ev.request.text_token_out = runtime_ev.ctx.best_index; } }; @@ -1053,10 +1006,12 @@ struct effect_bind_depformer_kv { ctx.depformer_kv.cache, runtime_ev.request.model, runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, runtime_ev.ctx.depformer_kv); - if (runtime_ev.ctx.depformer_kv_bound && - runtime_ev.ctx.depformer_kv.offset != nullptr) { - *runtime_ev.ctx.depformer_kv.offset = 0; - } + } +}; + +struct effect_reset_depformer_kv_offset { + void operator()(const event::step_run &runtime_ev, context &) const noexcept { + *runtime_ev.ctx.depformer_kv.offset = 0; } }; @@ -1402,13 +1357,12 @@ struct effect_run_depformer_layer_attention { layer_offset + static_cast(physical) * static_cast(dep_dim) + static_cast(head_offset + dim); - sum += - static_cast( - emel::kernel::detail::bf16_to_fp32( - view.value_cache[value_index]) * - emel::kernel::detail::bf16_to_fp32( - runtime_ev.ctx.attention_weights_bf16[static_cast( - physical)])); + sum += static_cast( + emel::kernel::detail::bf16_to_fp32( + view.value_cache[value_index]) * + emel::kernel::detail::bf16_to_fp32( + runtime_ev.ctx + .attention_weights_bf16[static_cast(physical)])); } attention_head[dim] = static_cast(sum); } @@ -1561,8 +1515,7 @@ struct effect_run_depformer_layer_silu_gate_silu { context &ctx) const noexcept { const auto *linear_in = detail::find_depformer_codebook_tensor( runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, - "gating.%d.linear_in.weight", - runtime_ev.ctx.depformer_weight_index); + "gating.%d.linear_in.weight", runtime_ev.ctx.depformer_weight_index); const uint64_t projection_dim = static_cast(linear_in->dims[1]); const uint64_t gate_dim = projection_dim / 2u; runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; @@ -1589,8 +1542,7 @@ struct effect_run_depformer_layer_silu_gate_mul { context &ctx) const noexcept { const auto *linear_in = detail::find_depformer_codebook_tensor( runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, - "gating.%d.linear_in.weight", - runtime_ev.ctx.depformer_weight_index); + "gating.%d.linear_in.weight", runtime_ev.ctx.depformer_weight_index); const uint64_t projection_dim = static_cast(linear_in->dims[1]); const uint64_t gate_dim = projection_dim / 2u; const float *right = runtime_ev.ctx.gating_projection.data() + gate_dim; @@ -1744,14 +1696,42 @@ struct effect_compute_depformer_token_logits { } }; -struct effect_sample_depformer_token { +struct effect_scale_depformer_sampling_logits { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + detail::scale_sampling_logits(runtime_ev.ctx.logits, ctx.session.audio_card, + ctx.sampling.audio_temperature); + } +}; + +struct effect_compute_depformer_sampling_probabilities { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + detail::compute_sampling_probabilities(runtime_ev.ctx.logits, + ctx.session.audio_card); + } +}; + +struct effect_compute_depformer_sampling_top_k { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + detail::compute_sampling_top_k( + runtime_ev.ctx.logits, runtime_ev.ctx.sampling_indices, + runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, + ctx.session.audio_card, ctx.sampling.audio_top_k); + } +}; + +struct effect_select_depformer_sampling_token { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - runtime_ev.ctx.depformer_sampling_ok = - sampling_ns::sample_top_k_exponential( - runtime_ev.ctx, ctx.session.audio_card, ctx.sampling.audio_top_k, - ctx.sampling.audio_temperature); - runtime_ev.ctx.depformer_logits_ok = runtime_ev.ctx.depformer_sampling_ok; + detail::compute_sampling_exponential_argmax( + runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, + ctx.session.audio_card, ctx.sampling.audio_top_k, + ctx.sampling.random_state, runtime_ev.ctx.best_index, + runtime_ev.ctx.best_score); + runtime_ev.ctx.depformer_sampling_ok = true; + runtime_ev.ctx.depformer_logits_ok = true; } }; diff --git a/src/emel/speech/generator/moshi/executor/context.hpp b/src/emel/speech/generator/moshi/executor/context.hpp index 22519a79..9d605650 100644 --- a/src/emel/speech/generator/moshi/executor/context.hpp +++ b/src/emel/speech/generator/moshi/executor/context.hpp @@ -50,7 +50,7 @@ struct sampling_config { float text_temperature = 0.0f; int32_t audio_top_k = 0; int32_t text_top_k = 0; - uint32_t seed = 1u; + uint32_t random_state = 1u; }; struct context { diff --git a/src/emel/speech/generator/moshi/executor/detail.hpp b/src/emel/speech/generator/moshi/executor/detail.hpp index ae4871b0..69666455 100644 --- a/src/emel/speech/generator/moshi/executor/detail.hpp +++ b/src/emel/speech/generator/moshi/executor/detail.hpp @@ -1,8 +1,11 @@ #pragma once +#include +#include #include #include #include +#include #include #include @@ -304,4 +307,63 @@ inline bool token_in_embedding_range(const int32_t token, return token >= k_token_zero && token <= card; } +inline void scale_sampling_logits(std::span logits, const int32_t card, + const float temperature) noexcept { + const float inverse_temperature = 1.0f / temperature; + for (int32_t index = 0; index < card; ++index) { + logits[static_cast(index)] *= inverse_temperature; + } +} + +inline void compute_sampling_probabilities(std::span logits, + const int32_t card) noexcept { + emel::kernel::detail::soft_max_row_ggml(card, logits.data()); +} + +inline void compute_sampling_top_k(std::span probabilities, + std::span sorted_indices, + std::span top_probabilities, + std::span top_indices, + const int32_t card, + const int32_t requested_top_k) noexcept { + for (int32_t index = 0; index < card; ++index) { + sorted_indices[static_cast(index)] = index; + } + std::sort(sorted_indices.begin(), sorted_indices.begin() + card, + [probabilities](const int32_t lhs, const int32_t rhs) { + return probabilities[static_cast(lhs)] > + probabilities[static_cast(rhs)]; + }); + for (int32_t slot = 0; slot < requested_top_k; ++slot) { + const int32_t index = sorted_indices[static_cast(slot)]; + top_probabilities[static_cast(slot)] = + probabilities[static_cast(index)]; + top_indices[static_cast(slot)] = index; + } +} + +inline void compute_sampling_exponential_argmax( + std::span top_probabilities, + std::span top_indices, const int32_t card, + const int32_t requested_top_k, uint32_t &random_state, int32_t &best_index, + float &best_score) noexcept { + constexpr uint32_t multiplier = 16807u; + constexpr uint32_t modulus = 2147483647u; + constexpr float random_max = 2147483647.0f; + (void)card; + best_index = -1; + best_score = -std::numeric_limits::infinity(); + for (int32_t slot = 0; slot < requested_top_k; ++slot) { + random_state = static_cast( + (static_cast(random_state) * multiplier) % modulus); + const float uniform = static_cast(random_state) / random_max; + const float divisor = -std::log(uniform); + const float score = top_probabilities[static_cast(slot)] / divisor; + if (score > best_score) { + best_score = score; + best_index = top_indices[static_cast(slot)]; + } + } +} + } // namespace emel::speech::generator::moshi::executor::detail diff --git a/src/emel/speech/generator/moshi/executor/events.hpp b/src/emel/speech/generator/moshi/executor/events.hpp index 20a3ee55..0e2ae965 100644 --- a/src/emel/speech/generator/moshi/executor/events.hpp +++ b/src/emel/speech/generator/moshi/executor/events.hpp @@ -107,8 +107,10 @@ struct step_ctx { detail::tensor_view projection_view = {}; alignas(64) std::array logits = {}; alignas(64) std::array top_scores = {}; + alignas( + 64) std::array top_indices = {}; alignas(64) - std::array top_indices = {}; + std::array sampling_indices = {}; alignas(64) std::array row = {}; alignas(64) std::array hidden = {}; alignas(64) std::array transformer_out = {}; diff --git a/src/emel/speech/generator/moshi/executor/guards.hpp b/src/emel/speech/generator/moshi/executor/guards.hpp index 5d78a0aa..93794455 100644 --- a/src/emel/speech/generator/moshi/executor/guards.hpp +++ b/src/emel/speech/generator/moshi/executor/guards.hpp @@ -29,6 +29,52 @@ struct guard_bind_contract_invalid { } }; +struct guard_sampling_seed_nonzero { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.sampling_seed != 0u; + } +}; + +struct guard_sampling_seed_zero { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.sampling_seed == 0u; + } +}; + +struct guard_text_sampling_top_k_within_card { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.sampling_text_top_k <= + runtime_ev.request.model.moshi_lm.text_card; + } +}; + +struct guard_text_sampling_top_k_exceeds_card { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.sampling_text_top_k > + runtime_ev.request.model.moshi_lm.text_card; + } +}; + +struct guard_audio_sampling_top_k_within_card { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.sampling_audio_top_k <= + runtime_ev.request.model.moshi_lm.card; + } +}; + +struct guard_audio_sampling_top_k_exceeds_card { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.sampling_audio_top_k > + runtime_ev.request.model.moshi_lm.card; + } +}; + struct guard_step_model_matches { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { @@ -500,8 +546,7 @@ struct guard_temporal_layer_attention_supported { lm.num_heads <= 0 || hidden_dim % lm.num_heads != 0 || head_dim <= 0 || static_cast(head_dim) > detail::k_max_hidden_dim || sequence_length <= 0 || capacity <= 0 || - static_cast(capacity) > - detail::k_max_temporal_context || + static_cast(capacity) > detail::k_max_temporal_context || view.kv_dim != hidden_dim || layer < 0 || layer >= view.layer_count || view.layer_cache_offsets.empty() || static_cast(layer) >= view.layer_cache_offsets.size()) { @@ -512,11 +557,11 @@ struct guard_temporal_layer_attention_supported { const size_t dim = static_cast(hidden_dim); const int32_t logical_begin = sequence_length > capacity ? sequence_length - capacity : 0; - for (int32_t logical = logical_begin; logical < sequence_length; ++logical) { + for (int32_t logical = logical_begin; logical < sequence_length; + ++logical) { const int32_t physical = detail::physical_position( snapshot, runtime_ev.request.sequence_id, logical); - if (physical < 0 || - physical >= capacity) { + if (physical < 0 || physical >= capacity) { return false; } const size_t begin = layer_offset + static_cast(physical) * dim; @@ -919,6 +964,7 @@ struct guard_text_sampling_config_valid { const action::context &ctx) const noexcept { return ctx.sampling.enabled && ctx.sampling.text_temperature > 0.0f && ctx.sampling.text_top_k > 0 && + ctx.sampling.text_top_k <= ctx.session.text_card && static_cast(ctx.session.text_card) <= detail::k_max_sampling_card && static_cast(ctx.sampling.text_top_k) <= @@ -1024,6 +1070,37 @@ struct guard_text_logits_failed { } }; +struct guard_text_sampling_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.text_sampling_ok; + } +}; + +struct guard_text_sampling_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_text_sampling_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_sampled_text_token_ready { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_text_sampling_succeeded{}(runtime_ev, ctx) && + guard_forced_text_token_absent{}(runtime_ev, ctx); + } +}; + +struct guard_forced_text_sampling_consumed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_text_sampling_succeeded{}(runtime_ev, ctx) && + guard_forced_text_token_valid_and_sampling_consume{}(runtime_ev, + ctx); + } +}; + struct guard_depformer_kv_binding_present { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { @@ -1065,8 +1142,7 @@ struct guard_depformer_scheduled_weight_present { const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; if (lm.depformer_weight_schedule_count == 0u || codebook < 0 || - static_cast(codebook) >= - lm.depformer_weight_schedule_count) { + static_cast(codebook) >= lm.depformer_weight_schedule_count) { return false; } const int32_t weight_index = @@ -1783,6 +1859,7 @@ struct guard_depformer_sampling_config_valid { const action::context &ctx) const noexcept { return ctx.sampling.enabled && ctx.sampling.audio_temperature > 0.0f && ctx.sampling.audio_top_k > 0 && + ctx.sampling.audio_top_k <= ctx.session.audio_card && static_cast(ctx.session.audio_card) <= detail::k_max_sampling_card && static_cast(ctx.sampling.audio_top_k) <= @@ -1798,6 +1875,20 @@ struct guard_depformer_sampling_config_invalid { } }; +struct guard_depformer_sampling_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_sampling_ok; + } +}; + +struct guard_depformer_sampling_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_sampling_succeeded{}(runtime_ev, ctx); + } +}; + struct guard_depformer_logits_argmax { bool operator()(const event::step_run &, const action::context &ctx) const noexcept { diff --git a/src/emel/speech/generator/moshi/executor/sm.hpp b/src/emel/speech/generator/moshi/executor/sm.hpp index 72e198db..0c7b2685 100644 --- a/src/emel/speech/generator/moshi/executor/sm.hpp +++ b/src/emel/speech/generator/moshi/executor/sm.hpp @@ -12,6 +12,9 @@ namespace emel::speech::generator::moshi::executor { struct state_uninitialized {}; struct state_bind_contract_decision {}; +struct state_sampling_seed_decision {}; +struct state_text_sampling_top_k_decision {}; +struct state_audio_sampling_top_k_decision {}; struct state_init_error_out_decision {}; struct state_init_callback_decision {}; struct state_init_failed_error_out_decision {}; @@ -86,9 +89,10 @@ struct state_text_logits_bind_result_decision {}; struct state_text_logits_run {}; struct state_text_logits_sample_projection {}; struct state_text_logits_sample_projection_result_decision {}; +struct state_text_logits_sample_scale {}; +struct state_text_logits_sample_softmax {}; +struct state_text_logits_sample_top_k {}; struct state_text_logits_sample_select {}; -struct state_forced_text_sampling_consume {}; -struct state_forced_text_sampling_result_decision {}; struct state_text_logits_result_decision {}; struct state_bind_depformer_kv {}; struct state_depformer_kv_result_decision {}; @@ -145,6 +149,9 @@ struct state_depformer_logits_bind_result_decision {}; struct state_depformer_logits_run {}; struct state_depformer_logits_sample_projection {}; struct state_depformer_logits_sample_projection_result_decision {}; +struct state_depformer_logits_sample_scale {}; +struct state_depformer_logits_sample_softmax {}; +struct state_depformer_logits_sample_top_k {}; struct state_depformer_logits_sample_select {}; struct state_depformer_token_publish {}; struct state_depformer_logits_result_decision {}; @@ -164,12 +171,30 @@ struct model { // Bind the Moshi LM execution contract. sml::state <= *sml::state + sml::event - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_bind_contract_valid{} ] / action::effect_bind_contract{} , sml::state <= sml::state + sml::completion [ guard::guard_bind_contract_invalid{} ] / action::effect_mark_bind_failed{} + , sml::state <= sml::state + + sml::completion [ guard::guard_sampling_seed_nonzero{} ] + / action::effect_bind_nonzero_sampling_seed{} + , sml::state <= sml::state + + sml::completion [ guard::guard_sampling_seed_zero{} ] + / action::effect_bind_zero_sampling_seed{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_sampling_top_k_within_card{} ] + / action::effect_bind_requested_text_sampling_top_k{} + , sml::state <= sml::state + + sml::completion [ guard::guard_text_sampling_top_k_exceeds_card{} ] + / action::effect_bind_full_card_text_sampling_top_k{} + , sml::state <= sml::state + + sml::completion [ guard::guard_audio_sampling_top_k_within_card{} ] + / action::effect_bind_requested_audio_sampling_top_k{} + , sml::state <= sml::state + + sml::completion [ guard::guard_audio_sampling_top_k_exceeds_card{} ] + / action::effect_bind_full_card_audio_sampling_top_k{} , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] / action::effect_store_error_out{} @@ -514,9 +539,9 @@ struct model { / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_forced_text_token_valid_and_sampling_consume{} ] - / action::effect_consume_forced_text_sampling{} + / action::effect_compute_text_token_logits{} , sml::state <= sml::state + sml::completion [ guard::guard_forced_text_token_valid_without_sampling_consume{} ] / action::effect_publish_forced_text_token{} @@ -535,26 +560,31 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_projection_view_bind_failed{} ] / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state - + sml::completion [ guard::guard_text_logits_matmul_succeeded{} ] - / action::effect_publish_forced_text_token{} - , sml::state <= sml::state - + sml::completion [ guard::guard_text_logits_matmul_failed{} ] - / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state - + sml::completion , sml::state <= sml::state + sml::completion - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_matmul_succeeded{} ] - / action::effect_sample_text_token{} + / action::effect_scale_text_sampling_logits{} , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_matmul_failed{} ] / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + / action::effect_compute_text_sampling_probabilities{} + , sml::state <= sml::state + + sml::completion + / action::effect_compute_text_sampling_top_k{} + , sml::state <= sml::state + + sml::completion + / action::effect_select_text_sampling_token{} , sml::state <= sml::state - + sml::completion [ guard::guard_text_logits_succeeded{} ] + + sml::completion [ guard::guard_sampled_text_token_ready{} ] + / action::effect_publish_sampled_text_token{} + , sml::state <= sml::state + + sml::completion [ guard::guard_forced_text_sampling_consumed{} ] + / action::effect_publish_forced_text_token{} , sml::state <= sml::state - + sml::completion [ guard::guard_text_logits_failed{} ] + + sml::completion [ guard::guard_text_sampling_failed{} ] / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_succeeded{} ] @@ -569,6 +599,7 @@ struct model { / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_kv_bound{} ] + / action::effect_reset_depformer_kv_offset{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_kv_bind_failed{} ] / action::effect_mark_graph_execution_unsupported{} @@ -829,12 +860,21 @@ struct model { / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_depformer_logits_matmul_succeeded{} ] - / action::effect_sample_depformer_token{} + / action::effect_scale_depformer_sampling_logits{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_logits_matmul_failed{} ] / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion + / action::effect_compute_depformer_sampling_probabilities{} + , sml::state <= sml::state + + sml::completion + / action::effect_compute_depformer_sampling_top_k{} + , sml::state <= sml::state + + sml::completion + / action::effect_select_depformer_sampling_token{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_layer_norm_supported{} ] / action::effect_run_depformer_layer_norm_rms{} @@ -848,10 +888,10 @@ struct model { + sml::completion [ guard::guard_depformer_logits_failed{} ] / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state - + sml::completion [ guard::guard_depformer_logits_succeeded{} ] + + sml::completion [ guard::guard_depformer_sampling_succeeded{} ] / action::effect_publish_depformer_token{} , sml::state <= sml::state - + sml::completion [ guard::guard_depformer_logits_failed{} ] + + sml::completion [ guard::guard_depformer_sampling_failed{} ] / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion diff --git a/tests/kernel/aarch64_tests.cpp b/tests/kernel/aarch64_tests.cpp index ced9491f..b9c501d2 100644 --- a/tests/kernel/aarch64_tests.cpp +++ b/tests/kernel/aarch64_tests.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,67 @@ make_row_sliced_lane_event(const emel::kernel::event::op_mul_mat &ev, return sliced; } +float compute_ggml_q4_k_q8_k_row( + const emel::kernel::detail::quant::block_q4_k *lhs, + const emel::kernel::detail::quant::block_q8_k *rhs, + const size_t block_count) { + constexpr uint32_t kmask1 = 0x3f3f3f3fu; + constexpr uint32_t kmask2 = 0x0f0f0f0fu; + constexpr uint32_t kmask3 = 0x03030303u; + float sum = 0.0f; + + for (size_t block = 0; block < block_count; ++block) { + uint32_t decoded_words[4] = {}; + std::memcpy(decoded_words, lhs[block].scales.data(), + lhs[block].scales.size()); + decoded_words[3] = ((decoded_words[2] >> 4u) & kmask2) | + (((decoded_words[1] >> 6u) & kmask3) << 4u); + const uint32_t decoded_aux = decoded_words[1] & kmask1; + decoded_words[1] = (decoded_words[2] & kmask2) | + (((decoded_words[0] >> 6u) & kmask3) << 4u); + decoded_words[2] = decoded_aux; + decoded_words[0] &= kmask1; + + const auto *scales = reinterpret_cast(decoded_words); + const auto *mins = reinterpret_cast(decoded_words + 2); + int32_t min_sum = 0; + for (size_t index = 0; index < 8u; ++index) { + const int32_t pair_sum = + static_cast(rhs[block].bsums[index * 2u]) + + static_cast(rhs[block].bsums[index * 2u + 1u]); + min_sum += pair_sum * static_cast(mins[index]); + } + + const uint8_t *q4 = lhs[block].qs.data(); + const int8_t *q8 = rhs[block].qs.data(); + int32_t low_sum = 0; + int32_t high_sum = 0; + for (size_t group = 0; group < 4u; ++group) { + int32_t low_dot = 0; + int32_t high_dot = 0; + for (size_t index = 0; index < 32u; ++index) { + low_dot += static_cast(q4[index] & 0x0fu) * + static_cast(q8[index]); + high_dot += static_cast(q4[index] >> 4u) * + static_cast(q8[index + 32u]); + } + low_sum += low_dot * static_cast(scales[group * 2u]); + high_sum += high_dot * static_cast(scales[group * 2u + 1u]); + q4 += 32u; + q8 += 64u; + } + + const float d = + emel::kernel::detail::quant::fp16_to_fp32(lhs[block].d) * rhs[block].d; + const float dmin = + emel::kernel::detail::quant::fp16_to_fp32(lhs[block].dmin) * + rhs[block].d; + sum -= dmin * static_cast(min_sum); + sum += d * static_cast(low_sum + high_sum); + } + return sum; +} + } // namespace TEST_CASE("kernel_aarch64_numeric_paths") { @@ -1376,6 +1438,56 @@ TEST_CASE("kernel_aarch64_q4_k_row_neon_matches_scalar") { #endif } +TEST_CASE("kernel_aarch64_q4_k_row_matches_ggml_accumulation_order") { +#if !(defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD)) + CHECK(true); +#else + using emel::kernel::detail::quant::block_q4_k; + using emel::kernel::detail::quant::block_q8_k; + using emel::kernel::detail::quant::QK_K; + + constexpr size_t block_count = 64u; + std::array q4_blocks = {}; + std::array q8_blocks = {}; + for (size_t block = 0; block < block_count; ++block) { + auto &q4 = q4_blocks[block]; + auto &q8 = q8_blocks[block]; + q4.d = emel::kernel::detail::quant::fp32_to_fp16( + 0.0009765625f * static_cast((block % 31u) + 1u)); + q4.dmin = emel::kernel::detail::quant::fp32_to_fp16( + 0.00048828125f * static_cast((block % 29u) + 1u)); + q8.d = 0.000244140625f * static_cast((block % 23u) + 1u); + for (size_t index = 0; index < q4.scales.size(); ++index) { + q4.scales[index] = + static_cast((block * 37u + index * 19u + 0x5au) & 0xffu); + } + for (size_t index = 0; index < q4.qs.size(); ++index) { + q4.qs[index] = + static_cast((block * 17u + index * 29u + 0x96u) & 0xffu); + } + for (size_t index = 0; index < q8.qs.size(); ++index) { + q8.qs[index] = static_cast( + static_cast((block * 13u + index * 7u) % 255u) - 127); + } + for (size_t group = 0; group < q8.bsums.size(); ++group) { + int32_t group_sum = 0; + for (size_t index = 0; index < 16u; ++index) { + group_sum += static_cast(q8.qs[group * 16u + index]); + } + q8.bsums[group] = static_cast(group_sum); + } + } + + const float expected = compute_ggml_q4_k_q8_k_row( + q4_blocks.data(), q8_blocks.data(), block_count); + const float actual = emel::kernel::aarch64::detail::dot_q4_k_q8_k_row_neon( + q4_blocks.data(), q8_blocks.data(), block_count); + + CHECK(actual == expected); +#endif +} + TEST_CASE("kernel_aarch64_q4_k_2rows_neon_matches_scalar") { #if !(defined(__aarch64__) || defined(__ARM_NEON)) CHECK(true); diff --git a/tests/kernel/lifecycle_tests.cpp b/tests/kernel/lifecycle_tests.cpp index ba6e9880..038bb314 100644 --- a/tests/kernel/lifecycle_tests.cpp +++ b/tests/kernel/lifecycle_tests.cpp @@ -731,6 +731,58 @@ TEST_CASE("kernel_soft_max_row_matches_ggml_arm64_neon_bits") { #endif } +TEST_CASE("kernel_rms_norm_matches_ggml_float_square_order") { + std::array src = {}; + constexpr float eps = 1.0e-8f; + float scale = 0.0f; + uint32_t fixture_seed = 0u; + for (uint32_t seed = 1u; seed <= 4096u; ++seed) { + uint32_t state = seed; + for (size_t index = 0; index < src.size(); ++index) { + state = state * 1664525u + 1013904223u; + const int32_t centered = static_cast(state & 0xffffu) - 32768; + const int exponent = static_cast((state >> 16u) % 18u) - 12; + src[index] = + std::ldexp(static_cast(centered) / 32768.0f, exponent); + } + + double ggml_sum = 0.0; + double widened_sum = 0.0; + for (const float value : src) { + ggml_sum += static_cast(value * value); + widened_sum += static_cast(value) * static_cast(value); + } + const float mean = static_cast(ggml_sum / src.size()); + const float widened_mean = static_cast(widened_sum / src.size()); + scale = 1.0f / std::sqrt(mean + eps); + const float widened_scale = 1.0f / std::sqrt(widened_mean + eps); + if (std::bit_cast(scale) != + std::bit_cast(widened_scale)) { + fixture_seed = seed; + break; + } + } + REQUIRE(fixture_seed != 0u); + std::array expected = {}; + for (size_t index = 0; index < src.size(); ++index) { + expected[index] = src[index] * scale; + } + + std::array actual = {}; + emel::kernel::event::op_rms_norm rms_ev{ + .src0 = make_src(src.data(), dtype::f32, src.size()), + .dst = make_dst(actual.data(), dtype::f32, actual.size()), + }; + std::memcpy(rms_ev.op_params.data(), &eps, sizeof(eps)); + rms_ev.op_params_size = sizeof(eps); + REQUIRE(emel::kernel::detail::run_rms_norm(rms_ev)); + + for (size_t index = 0; index < actual.size(); ++index) { + CHECK(std::bit_cast(actual[index]) == + std::bit_cast(expected[index])); + } +} + TEST_CASE("kernel_backends_reject_quantized_dispatch_dtypes") { float src0[4] = {1.0f, 2.0f, 3.0f, 4.0f}; float src1[4] = {4.0f, 3.0f, 2.0f, 1.0f}; diff --git a/tests/speech/generator/moshi_lifecycle_tests.cpp b/tests/speech/generator/moshi_lifecycle_tests.cpp index 3699f270..f372b9a9 100644 --- a/tests/speech/generator/moshi_lifecycle_tests.cpp +++ b/tests/speech/generator/moshi_lifecycle_tests.cpp @@ -890,6 +890,54 @@ TEST_CASE("speech_moshi_executor_initializes_lm_fixture") { CHECK(err == emel::error::cast(moshi_executor::error::none)); } +TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + moshi_executor::sm executor{}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.sampling_enabled = true; + init.sampling_audio_temperature = 0.8f; + init.sampling_text_temperature = 0.7f; + init.sampling_audio_top_k = 1; + init.sampling_text_top_k = fixture.model->moshi_lm.text_card + 1; + init.sampling_seed = 0u; + init.error_out = &err; + + REQUIRE(executor.process_event(init)); + CHECK(err == emel::error::cast(moshi_executor::error::none)); +} + +TEST_CASE("speech_moshi_executor_sampling_matches_reference_probability_path") { + std::array logits = {}; + uint32_t logit_state = 1153427707u; + for (float &logit : logits) { + logit_state = static_cast( + (static_cast(logit_state) * 16807u) % 2147483647u); + logit = (static_cast(logit_state) / 2147483647.0f - 0.5f) * 16.0f; + } + std::array top_probabilities = {}; + std::array top_indices = {}; + std::array sorted_indices = {}; + uint32_t random_state = 1234u; + int32_t best_index = -1; + float best_score = 0.0f; + + moshi_executor::detail::scale_sampling_logits(logits, 2048, 0.8f); + moshi_executor::detail::compute_sampling_probabilities(logits, 2048); + moshi_executor::detail::compute_sampling_top_k( + logits, sorted_indices, top_probabilities, top_indices, 2048, 250); + moshi_executor::detail::compute_sampling_exponential_argmax( + top_probabilities, top_indices, 2048, 250, random_state, best_index, + best_score); + + CHECK(best_index == 1582); + CHECK(random_state == 1237704734u); +} + TEST_CASE("speech_moshi_executor_rejects_graph_step_before_initialize") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { @@ -904,8 +952,8 @@ TEST_CASE("speech_moshi_executor_rejects_graph_step_before_initialize") { emel::memory::view::snapshot snapshot{}; moshi::event::graph_step step{*fixture.model, snapshot, - std::span{input}, - std::span{output}, text_token}; + std::span{input}, + std::span{output}, text_token}; step.error_out = &err; CHECK_FALSE(executor.process_event(step)); @@ -921,6 +969,10 @@ TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / "moshi" / "executor" / "actions.hpp"); const std::string actions_source{action_bytes.begin(), action_bytes.end()}; + const auto detail_bytes = + read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + "moshi" / "executor" / "detail.hpp"); + const std::string detail_source{detail_bytes.begin(), detail_bytes.end()}; CHECK(source.find("infer_debug_phase") == std::string::npos); CHECK(source.find("debug_phase_out != nullptr") == std::string::npos); @@ -935,6 +987,8 @@ TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { std::string::npos); CHECK(actions_source.find("if (!detail::bind_tensor_view") == std::string::npos); + CHECK(actions_source.find("if (runtime_ev.ctx.depformer_kv_bound") == + std::string::npos); CHECK(actions_source.find("(void)detail::bind_tensor_view") == std::string::npos); CHECK(actions_source.find("effect_bind_input_text_embedding") != @@ -975,6 +1029,14 @@ TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { std::string::npos); CHECK(actions_source.find("effect_bind_depformer_token_logits") != std::string::npos); + CHECK(source.find("state_sampling_seed_decision") != std::string::npos); + CHECK(source.find("state_text_sampling_top_k_decision") != std::string::npos); + CHECK(source.find("state_audio_sampling_top_k_decision") != + std::string::npos); + CHECK(source.find("guard_sampling_seed_zero") != std::string::npos); + CHECK(actions_source.find("effect_bind_zero_sampling_seed") != + std::string::npos); + CHECK(detail_source.find("random_state == 0u") == std::string::npos); CHECK(actions_source.find("effect_publish_temporal_out_norm") != std::string::npos); CHECK(actions_source.find("struct effect_run_temporal_layer_norm {") == @@ -1840,6 +1902,82 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { [](const uint16_t value) { return value != 0u; })); } +TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { + auto first_fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + auto second_fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (first_fixture.model == nullptr || second_fixture.model == nullptr) { + return; + } + + temporal_kv_probe first_temporal{}; + temporal_kv_probe second_temporal{}; + depformer_kv_probe first_depformer{}; + depformer_kv_probe second_depformer{}; + moshi_executor::sm first{moshi_executor::bind_kv_caches( + moshi_executor::bind_temporal_kv_cache(&first_temporal, + temporal_kv_probe_bind), + moshi_executor::bind_depformer_kv_cache(&first_depformer, + depformer_kv_probe_bind))}; + moshi_executor::sm second{moshi_executor::bind_kv_caches( + moshi_executor::bind_temporal_kv_cache(&second_temporal, + temporal_kv_probe_bind), + moshi_executor::bind_depformer_kv_cache(&second_depformer, + depformer_kv_probe_bind))}; + emel::error::type first_err = emel::error::cast(moshi_executor::error::none); + emel::error::type second_err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize first_init{*first_fixture.model}; + moshi_executor::event::initialize second_init{*second_fixture.model}; + for (auto *init : {&first_init, &second_init}) { + init->sampling_enabled = true; + init->sampling_audio_temperature = 0.8f; + init->sampling_text_temperature = 0.7f; + init->sampling_audio_top_k = 250; + init->sampling_text_top_k = 25; + init->sampling_seed = 1234u; + } + first_init.error_out = &first_err; + second_init.error_out = &second_err; + REQUIRE(first.process_event(first_init)); + REQUIRE(second.process_event(second_init)); + + std::array input = {}; + std::array first_output = {}; + std::array second_output = {}; + input.fill(-1); + input[0] = first_fixture.model->moshi_lm.text_padding_id; + int32_t first_text_token = -1; + int32_t second_text_token = -1; + emel::memory::view::snapshot snapshot{}; + snapshot.max_sequences = 1; + snapshot.sequence_active[0] = 1; + snapshot.sequence_length_values[0] = 1; + snapshot.sequence_kv_block_count[0] = 1; + snapshot.sequence_kv_blocks[0][0] = 0; + const auto input_span = std::span{ + input.data(), static_cast(first_fixture.model->moshi_lm.n_q + 1)}; + moshi::event::graph_step first_step{ + *first_fixture.model, snapshot, input_span, + std::span{ + first_output.data(), + static_cast(first_fixture.model->moshi_lm.dep_q)}, + first_text_token}; + moshi::event::graph_step second_step{ + *second_fixture.model, snapshot, input_span, + std::span{ + second_output.data(), + static_cast(second_fixture.model->moshi_lm.dep_q)}, + second_text_token}; + first_step.error_out = &first_err; + second_step.error_out = &second_err; + + REQUIRE(first.process_event(first_step)); + REQUIRE(second.process_event(second_step)); + CHECK(first_text_token == second_text_token); + CHECK(std::equal(first_output.begin(), + first_output.begin() + first_fixture.model->moshi_lm.dep_q, + second_output.begin())); +} + TEST_CASE("speech_moshi_e2e_encodes_audio_generates_tokens_and_decodes_audio") { auto codec_fixture = load_fixture_or_skip("mimi-tiny.gguf"); auto lm_fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); From fa7f5b4f21016d0bc5667a1f8925b908e0db9f34 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Thu, 9 Jul 2026 20:24:25 -0500 Subject: [PATCH 03/61] fix: match Moshi AArch64 SiLU --- src/emel/kernel/aarch64/actions.hpp | 116 +++++++++++------- src/emel/kernel/aarch64/guards.hpp | 51 +++++++- src/emel/kernel/aarch64/sm.hpp | 5 + .../speech/generator/moshi/executor/sm.hpp | 1 + src/emel/speech/generator/moshi/sm.hpp | 1 + tests/kernel/aarch64_tests.cpp | 63 ++++++++-- 6 files changed, 176 insertions(+), 61 deletions(-) diff --git a/src/emel/kernel/aarch64/actions.hpp b/src/emel/kernel/aarch64/actions.hpp index 98a57788..31b1f426 100644 --- a/src/emel/kernel/aarch64/actions.hpp +++ b/src/emel/kernel/aarch64/actions.hpp @@ -83,16 +83,44 @@ inline constexpr bool simd_supported_request_v = std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v || - std::is_same_v; + std::is_same_v; -inline bool -unary_subop_supported_simd(const event::unary_subop subop) noexcept { - const auto subop_code = static_cast(subop); - return subop_code == static_cast(event::unary_subop::abs) || - subop_code == static_cast(event::unary_subop::neg) || - subop_code == static_cast(event::unary_subop::relu); +#if defined(__aarch64__) || defined(__ARM_NEON) +inline float32x4_t compute_neon_expf(const float32x4_t x) noexcept { + const float32x4_t r = vdupq_n_f32(0x1.8p23f); + const float32x4_t z = vfmaq_f32(r, x, vdupq_n_f32(0x1.715476p+0f)); + const float32x4_t n = vsubq_f32(z, r); + const float32x4_t b = vfmsq_f32(vfmsq_f32(x, n, vdupq_n_f32(0x1.62e4p-1f)), n, + vdupq_n_f32(0x1.7f7d1cp-20f)); + const uint32x4_t e = vshlq_n_u32(vreinterpretq_u32_f32(z), 23); + const float32x4_t k = vreinterpretq_f32_u32( + vaddq_u32(e, vreinterpretq_u32_f32(vdupq_n_f32(1.0f)))); + const uint32x4_t c = vcagtq_f32(n, vdupq_n_f32(126.0f)); + const float32x4_t u = vmulq_f32(b, b); + const float32x4_t j = + vfmaq_f32(vmulq_f32(vdupq_n_f32(0x1.ffffecp-1f), b), + vfmaq_f32(vfmaq_f32(vdupq_n_f32(0x1.fffdb6p-2f), + vdupq_n_f32(0x1.555e66p-3f), b), + vfmaq_f32(vdupq_n_f32(0x1.573e2ep-5f), + vdupq_n_f32(0x1.0e4020p-7f), b), + u), + u); + const uint32x4_t d = vandq_u32(vclezq_f32(n), vdupq_n_u32(0x82000000u)); + const float32x4_t s1 = + vreinterpretq_f32_u32(vaddq_u32(d, vdupq_n_u32(0x7f000000u))); + const float32x4_t s2 = vreinterpretq_f32_u32(vsubq_u32(e, d)); + return vbslq_f32( + vcagtq_f32(n, vdupq_n_f32(192.0f)), vmulq_f32(s1, s1), + vbslq_f32(c, vmulq_f32(vfmaq_f32(s2, s2, j), s1), vfmaq_f32(k, k, j))); +} + +inline float32x4_t compute_neon_silu(const float32x4_t x) noexcept { + const float32x4_t neg_x = vsubq_f32(vdupq_n_f32(0.0f), x); + const float32x4_t denominator = + vaddq_f32(vdupq_n_f32(1.0f), compute_neon_expf(neg_x)); + return vdivq_f32(x, denominator); } +#endif inline void execute_neon_unary_abs(const float *src, float *dst, const uint64_t count) noexcept { @@ -149,6 +177,24 @@ inline void execute_neon_unary_relu(const float *src, float *dst, #endif } +inline void execute_neon_unary_silu(const float *src, float *dst, + const uint64_t count) noexcept { +#if defined(__aarch64__) || defined(__ARM_NEON) + uint64_t i = 0; + for (; i + 4 <= count; i += 4) { + vst1q_f32(dst + i, compute_neon_silu(vld1q_f32(src + i))); + } + for (; i < count; ++i) { + const float v = src[i]; + dst[i] = v / (1.0f + std::exp(-v)); + } +#else + (void)src; + (void)dst; + (void)count; +#endif +} + template inline bool execute_neon_image_pointwise_f32( const emel_image_pointwise_f32_request &request) noexcept { @@ -877,12 +923,7 @@ inline bool can_use_neon(const request_type &request, ::emel::kernel::detail::tensor_element_count(request.dst); } - bool unary_supported = true; - if constexpr (std::is_same_v) { - unary_supported = unary_subop_supported_simd(request.subop); - } - - return base_supported && src1_supported && unary_supported && + return base_supported && src1_supported && (quantized_mul_mat || is_dense_contiguous(request.src0)) && is_dense_contiguous(request.dst); #endif @@ -8324,71 +8365,53 @@ inline bool execute_neon_mul_mat_prepared_f32_lhs_4row( #endif } -inline bool execute_neon_unary(const event::op_unary &request) noexcept { +inline void +execute_neon_unary_abs_request(const event::op_unary &request) noexcept { #if defined(__aarch64__) || defined(__ARM_NEON) - const uint8_t subop_code = static_cast(request.subop); - const size_t is_abs = static_cast( - subop_code == static_cast(event::unary_subop::abs)); - const size_t is_neg = static_cast( - subop_code == static_cast(event::unary_subop::neg)); - const size_t is_relu = static_cast( - subop_code == static_cast(event::unary_subop::relu)); - const size_t kernel_index = is_abs * 1u + is_neg * 2u + is_relu * 3u; const uint64_t count = ::emel::kernel::detail::tensor_element_count(request.dst); const float *src = static_cast(request.src0.data); float *dst = static_cast(request.dst.data); - using unary_kernel_t = void (*)(const float *, float *, uint64_t) noexcept; - constexpr unary_kernel_t noop_kernel = - +[](const float *, float *, uint64_t) noexcept {}; - constexpr std::array kernels = { - noop_kernel, - execute_neon_unary_abs, - execute_neon_unary_neg, - execute_neon_unary_relu, - }; - kernels[kernel_index](src, dst, count); - return kernel_index != 0u; + execute_neon_unary_abs(src, dst, count); #else (void)request; - return false; #endif } inline void -execute_neon_unary_abs_request(const event::op_unary &request) noexcept { +execute_neon_unary_neg_request(const event::op_unary &request) noexcept { #if defined(__aarch64__) || defined(__ARM_NEON) const uint64_t count = ::emel::kernel::detail::tensor_element_count(request.dst); const float *src = static_cast(request.src0.data); float *dst = static_cast(request.dst.data); - execute_neon_unary_abs(src, dst, count); + execute_neon_unary_neg(src, dst, count); #else (void)request; #endif } inline void -execute_neon_unary_neg_request(const event::op_unary &request) noexcept { +execute_neon_unary_relu_request(const event::op_unary &request) noexcept { #if defined(__aarch64__) || defined(__ARM_NEON) const uint64_t count = ::emel::kernel::detail::tensor_element_count(request.dst); const float *src = static_cast(request.src0.data); float *dst = static_cast(request.dst.data); - execute_neon_unary_neg(src, dst, count); + execute_neon_unary_relu(src, dst, count); #else (void)request; #endif } inline void -execute_neon_unary_relu_request(const event::op_unary &request) noexcept { +execute_neon_unary_silu_request(const event::op_unary &request) noexcept { #if defined(__aarch64__) || defined(__ARM_NEON) const uint64_t count = ::emel::kernel::detail::tensor_element_count(request.dst); const float *src = static_cast(request.src0.data); float *dst = static_cast(request.dst.data); - execute_neon_unary_relu(src, dst, count); + execute_neon_unary_silu(src, dst, count); #else (void)request; #endif @@ -8406,6 +8429,9 @@ execute_simd_unary_subop_unchecked(const event::op_unary &request) noexcept { if constexpr (subop == event::unary_subop::relu) { execute_neon_unary_relu_request(request); } + if constexpr (subop == event::unary_subop::silu) { + execute_neon_unary_silu_request(request); + } } template @@ -8434,9 +8460,6 @@ inline void execute_simd_unchecked(const request_type &request) noexcept { if constexpr (std::is_same_v) { (void)execute_neon_mul_mat(request); } - if constexpr (std::is_same_v) { - (void)execute_neon_unary(request); - } } template @@ -8465,9 +8488,6 @@ inline bool execute_simd(const request_type &request) noexcept { if constexpr (std::is_same_v) { return execute_neon_mul_mat(request); } - if constexpr (std::is_same_v) { - return execute_neon_unary(request); - } return false; } @@ -9149,6 +9169,8 @@ using exec_simd_op_unary_neg_t = detail::exec_simd_unary_op<::emel::kernel::event::unary_subop::neg>; using exec_simd_op_unary_relu_t = detail::exec_simd_unary_op<::emel::kernel::event::unary_subop::relu>; +using exec_simd_op_unary_silu_t = + detail::exec_simd_unary_op<::emel::kernel::event::unary_subop::silu>; using exec_scalar_op_unary_abs_t = ::emel::kernel::detail::exec_scalar_unary_op< ::emel::kernel::aarch64::event::dispatch_op_unary, context, detail::mark_done_op, ::emel::kernel::event::unary_subop::abs>; diff --git a/src/emel/kernel/aarch64/guards.hpp b/src/emel/kernel/aarch64/guards.hpp index 5f98e915..14bae548 100644 --- a/src/emel/kernel/aarch64/guards.hpp +++ b/src/emel/kernel/aarch64/guards.hpp @@ -296,6 +296,25 @@ inline bool can_use_neon_conv_transpose_1d_f32( sizeof(float); } +inline bool +can_use_neon_unary_f32(const ::emel::kernel::event::op_unary &request, + const bool neon_available) noexcept { +#if !(defined(__aarch64__) || defined(__ARM_NEON)) + (void)request; + (void)neon_available; + return false; +#else + return neon_available && + ::emel::kernel::detail::can_run_backend_request(request) && + ::emel::kernel::detail::dtype_code(request.src0.type) == + ::emel::kernel::detail::dtype_f32 && + ::emel::kernel::detail::dtype_code(request.dst.type) == + ::emel::kernel::detail::dtype_f32 && + ::emel::kernel::detail::is_dense_contiguous(request.src0) && + ::emel::kernel::detail::is_dense_contiguous(request.dst); +#endif +} + } // namespace detail template struct simd_op { @@ -804,6 +823,16 @@ template struct invalid_op { } }; +struct simd_op_unary_f32 { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_unary &ev, + const action::context &ctx) const noexcept { + if (!::emel::kernel::detail::validate_dispatch_request(ev.request)) { + return false; + } + return detail::can_use_neon_unary_f32(ev.request, ctx.neon_available); + } +}; + template <::emel::kernel::event::unary_subop subop> struct unary_subop_is { bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_unary &ev, const action::context &) const noexcept { @@ -814,8 +843,7 @@ template <::emel::kernel::event::unary_subop subop> struct unary_subop_is { template <::emel::kernel::event::unary_subop subop> using simd_op_unary_subop = ::emel::kernel::detail::simd_unary_subop_guard< ::emel::kernel::aarch64::event::dispatch_op_unary, action::context, - simd_op<::emel::kernel::aarch64::event::dispatch_op_unary>, - unary_subop_is>; + simd_op_unary_f32, unary_subop_is>; template <::emel::kernel::event::unary_subop subop> using valid_op_unary_subop = ::emel::kernel::detail::valid_unary_subop_guard< @@ -823,18 +851,29 @@ using valid_op_unary_subop = ::emel::kernel::detail::valid_unary_subop_guard< valid_op<::emel::kernel::aarch64::event::dispatch_op_unary>, unary_subop_is>; +template <::emel::kernel::event::unary_subop subop> +struct valid_scalar_op_unary_subop { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_unary &ev, + const action::context &ctx) const noexcept { + return valid_op_unary_subop{}(ev, ctx) && + !simd_op_unary_f32{}(ev, ctx); + } +}; + using simd_op_unary_abs = simd_op_unary_subop<::emel::kernel::event::unary_subop::abs>; using simd_op_unary_neg = simd_op_unary_subop<::emel::kernel::event::unary_subop::neg>; using simd_op_unary_relu = simd_op_unary_subop<::emel::kernel::event::unary_subop::relu>; +using simd_op_unary_silu = + simd_op_unary_subop<::emel::kernel::event::unary_subop::silu>; using valid_op_unary_abs = - valid_op_unary_subop<::emel::kernel::event::unary_subop::abs>; + valid_scalar_op_unary_subop<::emel::kernel::event::unary_subop::abs>; using valid_op_unary_neg = - valid_op_unary_subop<::emel::kernel::event::unary_subop::neg>; + valid_scalar_op_unary_subop<::emel::kernel::event::unary_subop::neg>; using valid_op_unary_relu = - valid_op_unary_subop<::emel::kernel::event::unary_subop::relu>; + valid_scalar_op_unary_subop<::emel::kernel::event::unary_subop::relu>; using valid_op_unary_exp = valid_op_unary_subop<::emel::kernel::event::unary_subop::exp>; using valid_op_unary_tanh = @@ -844,7 +883,7 @@ using valid_op_unary_elu = using valid_op_unary_gelu = valid_op_unary_subop<::emel::kernel::event::unary_subop::gelu>; using valid_op_unary_silu = - valid_op_unary_subop<::emel::kernel::event::unary_subop::silu>; + valid_scalar_op_unary_subop<::emel::kernel::event::unary_subop::silu>; // Variant predicates for the ops whose dtype/mode choice is modeled as // explicit transition rows (op_unary pattern). diff --git a/src/emel/kernel/aarch64/sm.hpp b/src/emel/kernel/aarch64/sm.hpp index 8089a516..9d7965fb 100644 --- a/src/emel/kernel/aarch64/sm.hpp +++ b/src/emel/kernel/aarch64/sm.hpp @@ -1167,6 +1167,11 @@ struct model { [ guard::simd_op_unary_relu{} ] / action::exec_simd_op_unary_relu + , sml::state <= sml::state + + sml::event<::emel::kernel::aarch64::event::dispatch_op_unary> + [ guard::simd_op_unary_silu{} ] + / action::exec_simd_op_unary_silu_t{} + , sml::state <= sml::state + sml::event<::emel::kernel::aarch64::event::dispatch_op_unary> [ guard::valid_op_unary_abs{} ] diff --git a/src/emel/speech/generator/moshi/executor/sm.hpp b/src/emel/speech/generator/moshi/executor/sm.hpp index 0c7b2685..a16638d1 100644 --- a/src/emel/speech/generator/moshi/executor/sm.hpp +++ b/src/emel/speech/generator/moshi/executor/sm.hpp @@ -1,4 +1,5 @@ #pragma once +// benchmark: designed #include diff --git a/src/emel/speech/generator/moshi/sm.hpp b/src/emel/speech/generator/moshi/sm.hpp index 78639a67..3c2cf690 100644 --- a/src/emel/speech/generator/moshi/sm.hpp +++ b/src/emel/speech/generator/moshi/sm.hpp @@ -1,4 +1,5 @@ #pragma once +// benchmark: designed #include diff --git a/tests/kernel/aarch64_tests.cpp b/tests/kernel/aarch64_tests.cpp index b9c501d2..7cd1b0ac 100644 --- a/tests/kernel/aarch64_tests.cpp +++ b/tests/kernel/aarch64_tests.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -5041,9 +5042,11 @@ TEST_CASE("kernel_aarch64_detail_branch_paths") { .subop = emel::kernel::event::unary_subop::relu, }; #if defined(__aarch64__) || defined(__ARM_NEON) - CHECK(emel::kernel::aarch64::detail::can_use_neon(unary_ev, true)); + CHECK(emel::kernel::aarch64::guard::detail::can_use_neon_unary_f32(unary_ev, + true)); #else - CHECK_FALSE(emel::kernel::aarch64::detail::can_use_neon(unary_ev, true)); + CHECK_FALSE(emel::kernel::aarch64::guard::detail::can_use_neon_unary_f32( + unary_ev, true)); #endif unary_ev.subop = emel::kernel::event::unary_subop::exp; CHECK_FALSE(emel::kernel::aarch64::detail::can_use_neon(unary_ev, true)); @@ -5183,7 +5186,8 @@ TEST_CASE("kernel_aarch64_detail_helper_edge_paths") { CHECK(emel::kernel::aarch64::detail::execute_neon_sqr(sqr_ev)); CHECK(emel::kernel::aarch64::detail::execute_neon_sqrt(sqrt_ev)); CHECK(emel::kernel::aarch64::detail::execute_neon_mul_mat(mul_mat_ev)); - CHECK(emel::kernel::aarch64::detail::execute_neon_unary(unary_ev)); + emel::kernel::aarch64::detail::execute_simd_unary_subop_unchecked< + emel::kernel::event::unary_subop::relu>(unary_ev); #else CHECK_FALSE(emel::kernel::aarch64::detail::execute_neon_dup(dup_ev)); CHECK_FALSE(emel::kernel::aarch64::detail::execute_neon_add(add_ev)); @@ -5193,7 +5197,6 @@ TEST_CASE("kernel_aarch64_detail_helper_edge_paths") { CHECK_FALSE(emel::kernel::aarch64::detail::execute_neon_sqr(sqr_ev)); CHECK_FALSE(emel::kernel::aarch64::detail::execute_neon_sqrt(sqrt_ev)); CHECK_FALSE(emel::kernel::aarch64::detail::execute_neon_mul_mat(mul_mat_ev)); - CHECK_FALSE(emel::kernel::aarch64::detail::execute_neon_unary(unary_ev)); #endif const bool simd_dup = emel::kernel::aarch64::detail::execute_simd(dup_ev); @@ -5205,7 +5208,6 @@ TEST_CASE("kernel_aarch64_detail_helper_edge_paths") { const bool simd_sqrt = emel::kernel::aarch64::detail::execute_simd(sqrt_ev); const bool simd_mul_mat = emel::kernel::aarch64::detail::execute_simd(mul_mat_ev); - const bool simd_unary = emel::kernel::aarch64::detail::execute_simd(unary_ev); (void)simd_dup; (void)simd_add; (void)simd_sub; @@ -5214,7 +5216,6 @@ TEST_CASE("kernel_aarch64_detail_helper_edge_paths") { (void)simd_sqr; (void)simd_sqrt; (void)simd_mul_mat; - (void)simd_unary; #if defined(__aarch64__) || defined(__ARM_NEON) CHECK(simd_dup); @@ -5225,7 +5226,6 @@ TEST_CASE("kernel_aarch64_detail_helper_edge_paths") { CHECK(simd_sqr); CHECK(simd_sqrt); CHECK(simd_mul_mat); - CHECK(simd_unary); #else CHECK_FALSE(simd_dup); CHECK_FALSE(simd_add); @@ -5235,7 +5235,6 @@ TEST_CASE("kernel_aarch64_detail_helper_edge_paths") { CHECK_FALSE(simd_sqr); CHECK_FALSE(simd_sqrt); CHECK_FALSE(simd_mul_mat); - CHECK_FALSE(simd_unary); #endif unary_ev.subop = emel::kernel::event::unary_subop::exp; @@ -5314,6 +5313,54 @@ TEST_CASE("kernel_aarch64_unary_subop_scalar_paths") { CHECK_FALSE(scalar_machine.process_event(unary_ev)); } +TEST_CASE("kernel_aarch64_neon_silu_matches_moshi_reference_activation") { +#if !(defined(__aarch64__) || defined(__ARM_NEON)) + return; +#else + const float src[5] = { + std::bit_cast(0x3a9dd9b3u), + std::bit_cast(0xbef68af7u), + std::bit_cast(0xbdc5f39au), + std::bit_cast(0xbf218bc1u), + 0.5f, + }; + float dst[5] = {}; + const emel::kernel::event::op_unary unary_ev{ + .src0 = make_src(src, dtype::f32, 5), + .dst = make_dst(dst, dtype::f32, 5), + .subop = emel::kernel::event::unary_subop::silu, + }; + aarch64_sm machine{emel::kernel::aarch64::action::context{true, {}, 0}}; + + REQUIRE(machine.process_event(unary_ev)); + CHECK(std::bit_cast(dst[0]) == 0x3a1df208u); + CHECK(std::bit_cast(dst[1]) == 0xbe3c4e19u); + CHECK(std::bit_cast(dst[2]) == 0xbd3c6475u); + CHECK(std::bit_cast(dst[3]) == 0xbe606749u); + CHECK(dst[4] == doctest::Approx(0.5f / (1.0f + std::exp(-0.5f)))); +#endif +} + +TEST_CASE("kernel_aarch64_simd_guards_reject_invalid_unary_and_argmax") { + const emel::kernel::event::op_unary invalid_unary{}; + const emel::kernel::event::op_mul_mat_argmax invalid_argmax{}; + emel::kernel::aarch64::event::dispatch_ctx dispatch_context{}; + const emel::kernel::aarch64::event::dispatch_op_unary unary_dispatch{ + invalid_unary, dispatch_context}; + const emel::kernel::aarch64::event::dispatch_op_mul_mat_argmax + argmax_dispatch{invalid_argmax, dispatch_context}; + const emel::kernel::aarch64::action::context guard_context{true, {}, 0}; + + CHECK_FALSE(emel::kernel::aarch64::guard::simd_op_unary_f32{}(unary_dispatch, + guard_context)); + CHECK_FALSE(emel::kernel::aarch64::guard:: + simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs{}( + argmax_dispatch, guard_context)); + CHECK_FALSE(emel::kernel::aarch64::guard:: + simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4{}( + argmax_dispatch, guard_context)); +} + TEST_CASE("kernel_aarch64_flash_attn_ext_reuses_persistent_workspace") { #if !(defined(__aarch64__) || defined(__ARM_NEON)) return; From 0e8737de64160cbdd53380fead28d41766b0c463 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Thu, 9 Jul 2026 22:17:35 -0500 Subject: [PATCH 04/61] feat: add PersonaPlex CPU speech comparison --- CMakeLists.txt | 1 + docs/benchmarking.md | 35 + scripts/bench_mimi_compare.sh | 17 + scripts/bench_personaplex_compare.sh | 134 ++++ scripts/setup_moshi_cpp_reference.sh | 33 +- scripts/setup_personaplex_mlx_reference.sh | 12 +- .../moshi/personaplex/session/actions.hpp | 315 +++++++++ .../moshi/personaplex/session/any.hpp | 10 + .../moshi/personaplex/session/context.hpp | 56 ++ .../moshi/personaplex/session/errors.hpp | 23 + .../moshi/personaplex/session/events.hpp | 217 ++++++ .../moshi/personaplex/session/guards.hpp | 188 ++++++ .../moshi/personaplex/session/sm.hpp | 297 +++++++++ tests/speech/generator/moshi_fixture.hpp | 136 ++++ .../generator/moshi_lifecycle_tests.cpp | 122 +--- .../moshi_personaplex_session_tests.cpp | 497 ++++++++++++++ tools/bench/CMakeLists.txt | 45 +- tools/bench/bench_dependency_manifest.cpp | 8 + tools/bench/dependency_manifest.txt | 2 + tools/bench/moshi_gguf_convert.py | 53 +- tools/bench/personaplex-inference.json | 28 + tools/bench/personaplex_compare.py | 368 ++++++++++ tools/bench/personaplex_compare_tests.cpp | 157 +++++ tools/bench/speech/moshi_reference_driver.cpp | 209 +++++- .../bench/speech/personaplex_emel_runner.cpp | 626 ++++++++++++++++++ 25 files changed, 3452 insertions(+), 137 deletions(-) create mode 100755 scripts/bench_personaplex_compare.sh create mode 100644 src/emel/speech/generator/moshi/personaplex/session/actions.hpp create mode 100644 src/emel/speech/generator/moshi/personaplex/session/any.hpp create mode 100644 src/emel/speech/generator/moshi/personaplex/session/context.hpp create mode 100644 src/emel/speech/generator/moshi/personaplex/session/errors.hpp create mode 100644 src/emel/speech/generator/moshi/personaplex/session/events.hpp create mode 100644 src/emel/speech/generator/moshi/personaplex/session/guards.hpp create mode 100644 src/emel/speech/generator/moshi/personaplex/session/sm.hpp create mode 100644 tests/speech/generator/moshi_fixture.hpp create mode 100644 tests/speech/generator/moshi_personaplex_session_tests.cpp create mode 100644 tools/bench/personaplex-inference.json create mode 100755 tools/bench/personaplex_compare.py create mode 100644 tools/bench/personaplex_compare_tests.cpp create mode 100644 tools/bench/speech/personaplex_emel_runner.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 804c3046..93753f0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,7 @@ if(EMEL_ENABLE_TESTS) tests/speech/codec/mimi_detail_tests.cpp tests/speech/codec/mimi_lifecycle_tests.cpp tests/speech/generator/moshi_lifecycle_tests.cpp + tests/speech/generator/moshi_personaplex_session_tests.cpp tests/speech/encoder/whisper/lifecycle_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp diff --git a/docs/benchmarking.md b/docs/benchmarking.md index 66ad0b93..b8bd6ebf 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -372,6 +372,41 @@ scripts/bench_moshi_lm_compare.sh \ pass `--system` on macOS hosts where zig links against a newer SDK than the runtime OS can load. + +## CPU-only PersonaPlex speech comparison + +to run real speech end to end through both EMEL and pinned moshi.cpp with the same fixed seed and +input samples: + +```bash +scripts/bench_personaplex_compare.sh +``` + +on macOS, the default input is generated with Samantha at 175 words per minute saying +`Hey, I'm Gabe. How are you doing?` directly as a mono 24 kHz signed 16-bit WAV. pass +`--audio /path/to/input.wav` on another Unix host or to use an existing recording. + +the comparison builds two isolated Release executables. `personaplex_emel_runner` links only EMEL +and drives the maintained Mimi and Moshi state machines. `moshi_reference_driver personaplex` links +only the pinned moshi.cpp/ggml reference lane. the reference configure hard-disables Metal and the +script injects `--threads 1`, seed `1234`, 125 frames, temperatures, and sampling limits; there are +no process-global EMEL sampling defaults. + +the pinned upstream JSON remains untouched for the reference lane. EMEL model conversion injects +the separate `tools/bench/personaplex-inference.json` contract, keeping prompt tokens, public +codebook count, and silence framing explicit and reproducible. the setup keeps the full 16-codebook +Mimi parity artifact separate from PersonaPlex's 8-public-codebook Mimi artifact. + +the report and both audible WAVs are written under `build/personaplex_compare/`. the report records +the input SHA256, exact public Mimi input-code match, sampled output-token match, text-token match, +lagged 80 ms energy correlation, activity ratio, non-silence, output hashes, and end-to-end wall +time. sampled output is compared as behavior rather than raw-waveform equality because a one-rank +floating-point difference can avalanche later fixed-seed draws even when the RNG state and sampling +policy agree. + +use `--frames`, `--seed`, `--threads`, `--output-dir`, `--build-only`, or `--run-only` to override +the injected run configuration. `--run-only` never fetches, converts, or rebuilds artifacts. + ## generation-specific local overrides the canonical generation case has its own bounded local validation knobs: diff --git a/scripts/bench_mimi_compare.sh b/scripts/bench_mimi_compare.sh index f9b45ce3..40f5d9e9 100755 --- a/scripts/bench_mimi_compare.sh +++ b/scripts/bench_mimi_compare.sh @@ -18,6 +18,7 @@ BUILD_DIR="${EMEL_MIMI_COMPARE_BUILD_DIR:-$ROOT_DIR/build/mimi_compare_tools}" OUTPUT_DIR="${EMEL_MIMI_COMPARE_OUTPUT_DIR:-$ROOT_DIR/build/mimi_compare}" ARTIFACT_DIR="${EMEL_MOSHI_REFERENCE_ARTIFACT_DIR:-$ROOT_DIR/build/moshi_reference}" MLX_ARTIFACT_DIR="${EMEL_PERSONAPLEX_MLX_ARTIFACT_DIR:-$ROOT_DIR/build/personaplex_mlx_reference}" +MODEL_CONFIG="$ARTIFACT_DIR/personaplex-config.json" BUILD_ONLY=false RUN_ONLY=false REFERENCE_BACKEND="moshi_cpp" @@ -70,6 +71,20 @@ if [[ -z "$PYTHON_BIN" ]]; then echo "error: required tool missing: python3 (or python3.12/python3.13)" >&2 exit 1 fi +if [[ ! -f "$MODEL_CONFIG" ]]; then + echo "error: missing pinned PersonaPlex model config: $MODEL_CONFIG" >&2 + exit 1 +fi +MIMI_N_Q="$($PYTHON_BIN - "$MODEL_CONFIG" <<'PY' +import json +import sys + +value = json.load(open(sys.argv[1], encoding="utf-8")).get("n_q") +if not isinstance(value, int) or value <= 0: + raise SystemExit("Mimi n_q must be a positive integer") +print(value) +PY +)" if ! $RUN_ONLY; then # full mode: fetch + sha256 verify + run the emel converter (no build) @@ -158,6 +173,7 @@ PY --emel-model "$EMEL_MODEL" \ --reference-model "$REFERENCE_MODEL" \ --audio "$AUDIO" \ + --n-q "$MIMI_N_Q" \ --compare-decode \ --prefix-streams "${EMEL_MIMI_MLX_PREFIX_STREAMS:-4}" \ --min-prefix-match "${EMEL_MIMI_MLX_MIN_PREFIX_MATCH:-0.90}" \ @@ -174,6 +190,7 @@ else --emel-model "$EMEL_MODEL" \ --reference-model "$REFERENCE_MODEL" \ --audio "$AUDIO" \ + --n-q "$MIMI_N_Q" \ --compare-decode \ --min-decode-psnr-db "${EMEL_MIMI_MIN_DECODE_PSNR_DB:-30}" \ --require-token-exact \ diff --git a/scripts/bench_personaplex_compare.sh b/scripts/bench_personaplex_compare.sh new file mode 100755 index 00000000..042e1c8a --- /dev/null +++ b/scripts/bench_personaplex_compare.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +# CPU-only, fixed-seed PersonaPlex speech comparison using isolated subprocess lanes. +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +# shellcheck source=scripts/build_jobs.sh +source "$ROOT_DIR/scripts/build_jobs.sh" + +BUILD_DIR="${EMEL_PERSONAPLEX_COMPARE_BUILD_DIR:-$ROOT_DIR/build/personaplex_compare_tools_zig}" +OUTPUT_DIR="${EMEL_PERSONAPLEX_COMPARE_OUTPUT_DIR:-$ROOT_DIR/build/personaplex_compare}" +ARTIFACT_DIR="${EMEL_MOSHI_REFERENCE_ARTIFACT_DIR:-$ROOT_DIR/build/moshi_reference}" +AUDIO="" +FRAMES=125 +SEED=1234 +THREADS=1 +BUILD_ONLY=false +RUN_ONLY=false + +usage() { + cat <<'USAGE' +usage: scripts/bench_personaplex_compare.sh [options] + + --audio PATH 24 kHz mono s16 WAV; default uses macOS say for + "Hey, I'm Gabe. How are you doing?" + --frames N generated frames per lane (default: 125 / 10 seconds) + --seed N fixed sampling seed (default: 1234) + --threads N CPU threads in moshi.cpp reference lane (default: 1) + --output-dir PATH output WAV/log/report directory + --build-only fetch/configure/build without running + --run-only use an existing build and artifacts +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --audio) AUDIO="${2:-}"; shift 2 ;; + --frames) FRAMES="${2:-}"; shift 2 ;; + --seed) SEED="${2:-}"; shift 2 ;; + --threads) THREADS="${2:-}"; shift 2 ;; + --output-dir) OUTPUT_DIR="${2:-}"; shift 2 ;; + --build-only) BUILD_ONLY=true; shift ;; + --run-only) RUN_ONLY=true; shift ;; + -h|--help) usage; exit 0 ;; + *) echo "error: unknown argument '$1'" >&2; usage; exit 1 ;; + esac +done + +if $BUILD_ONLY && $RUN_ONLY; then + echo "error: --build-only and --run-only are mutually exclusive" >&2 + exit 1 +fi +for value in "$FRAMES" "$SEED" "$THREADS"; do + if [[ ! "$value" =~ ^[1-9][0-9]*$ ]]; then + echo "error: frames, seed, and threads must be positive integers" >&2 + exit 1 + fi +done +for tool in cmake ninja git python3 zig; do + if ! command -v "$tool" >/dev/null 2>&1; then + echo "error: required tool missing: $tool" >&2 + exit 1 + fi +done + +if ! $RUN_ONLY; then + "$ROOT_DIR/scripts/setup_moshi_cpp_reference.sh" >/dev/null + zig_bin="$(command -v zig)" + cmake -S "$ROOT_DIR/tools/bench" -B "$BUILD_DIR" -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DEMEL_BENCH_SUITE_FILTER=speech_dialogue_moshi \ + -DEMEL_BENCH_SKIP_MOSHI_REFERENCE=OFF \ + -DCMAKE_C_COMPILER="$zig_bin" \ + -DCMAKE_C_COMPILER_ARG1=cc \ + -DCMAKE_CXX_COMPILER="$zig_bin" \ + -DCMAKE_CXX_COMPILER_ARG1=c++ \ + -DCMAKE_ASM_COMPILER="$zig_bin" \ + -DCMAKE_ASM_COMPILER_ARG1=cc \ + -DCMAKE_C_FLAGS=-fno-sanitize=undefined \ + -DCMAKE_CXX_FLAGS=-fno-sanitize=undefined + cmake --build "$BUILD_DIR" --parallel "$EMEL_BUILD_JOBS" \ + --target personaplex_emel_runner moshi_reference_driver +fi + +if $BUILD_ONLY; then + echo "PersonaPlex CPU comparison lanes built in $BUILD_DIR" + exit 0 +fi + +mkdir -p "$OUTPUT_DIR" +if [[ -z "$AUDIO" ]]; then + if ! command -v say >/dev/null 2>&1; then + echo "error: default organic input needs macOS say; pass --audio" >&2 + exit 1 + fi + AUDIO="$OUTPUT_DIR/say_gabe_how_are_you_24k.wav" + say -v Samantha -r 175 --file-format=WAVE --data-format=LEI16@24000 \ + --channels=1 -o "$AUDIO" "Hey, I'm Gabe. How are you doing?" +fi + +EMEL_RUNNER="$BUILD_DIR/personaplex_emel_runner" +REFERENCE_DRIVER="$BUILD_DIR/moshi_reference_driver" +EMEL_MIMI="$ARTIFACT_DIR/mimi-e351c8d8-125-personaplex-emel.gguf" +REFERENCE_MIMI="$ARTIFACT_DIR/mimi-e351c8d8-125.gguf" +EMEL_LM="$ARTIFACT_DIR/model-q4_k-emel.gguf" +REFERENCE_LM="$ARTIFACT_DIR/model-q4_k.gguf" +EMEL_VOICE="$ARTIFACT_DIR/voices/NATF0-emel.gguf" +REFERENCE_VOICE="$ARTIFACT_DIR/voices/NATF0.gguf" +CONFIG="$ARTIFACT_DIR/personaplex-config.json" +INFERENCE_CONFIG="$ROOT_DIR/tools/bench/personaplex-inference.json" +for path in "$AUDIO" "$EMEL_RUNNER" "$REFERENCE_DRIVER" "$EMEL_MIMI" \ + "$REFERENCE_MIMI" "$EMEL_LM" "$REFERENCE_LM" "$EMEL_VOICE" \ + "$REFERENCE_VOICE" "$CONFIG" "$INFERENCE_CONFIG"; do + if [[ ! -f "$path" ]]; then + echo "error: missing required artifact: $path" >&2 + exit 1 + fi +done + +python3 "$ROOT_DIR/tools/bench/personaplex_compare.py" \ + --emel-runner "$EMEL_RUNNER" \ + --reference-driver "$REFERENCE_DRIVER" \ + --emel-mimi "$EMEL_MIMI" \ + --reference-mimi "$REFERENCE_MIMI" \ + --emel-lm "$EMEL_LM" \ + --reference-lm "$REFERENCE_LM" \ + --emel-voice "$EMEL_VOICE" \ + --reference-voice "$REFERENCE_VOICE" \ + --config "$CONFIG" \ + --inference-config "$INFERENCE_CONFIG" \ + --audio "$AUDIO" \ + --output-dir "$OUTPUT_DIR" \ + --frames "$FRAMES" \ + --seed "$SEED" \ + --threads "$THREADS" diff --git a/scripts/setup_moshi_cpp_reference.sh b/scripts/setup_moshi_cpp_reference.sh index 6dc9c758..2df4b8f6 100755 --- a/scripts/setup_moshi_cpp_reference.sh +++ b/scripts/setup_moshi_cpp_reference.sh @@ -26,6 +26,7 @@ MOSHI_MODEL="$ARTIFACT_DIR/model-q4_k.gguf" MOSHI_MODEL_SHA256="73c4eb247740a48eebe5319ef767669dc8a06fd333b152a6cd6e12bacb64553d" MOSHI_CONFIG="$ARTIFACT_DIR/personaplex-config.json" MOSHI_CONFIG_SHA256="1b215765f6aafc6ef2592dadefcd8ad39c8b56d6eda25242be301b4af36b986a" +MOSHI_INFERENCE_CONFIG="$ROOT_DIR/tools/bench/personaplex-inference.json" MIMI_MODEL="$ARTIFACT_DIR/mimi-e351c8d8-125.gguf" MIMI_MODEL_SHA256="7e0c9ced83cbd035f70b82f1c5602673083fcccec006ea29f48d2e32c60ec697" TOKENIZER_MODEL="$ARTIFACT_DIR/tokenizer_spm_32k_3.model" @@ -36,6 +37,7 @@ REFERENCE_AUDIO="$ARTIFACT_DIR/phase_moshi_440hz_24khz_mono.wav" MOSHI_MODEL_EMEL="$ARTIFACT_DIR/model-q4_k-emel.gguf" MIMI_MODEL_EMEL="$ARTIFACT_DIR/mimi-e351c8d8-125-emel.gguf" +MIMI_MODEL_PERSONAPLEX_EMEL="$ARTIFACT_DIR/mimi-e351c8d8-125-personaplex-emel.gguf" VOICE_MODEL_EMEL="$ARTIFACT_DIR/voices/NATF0-emel.gguf" FETCH_ONLY=false @@ -109,10 +111,15 @@ fetch_pinned() { local url="$1" local path="$2" local expected_sha="$3" - if [[ ! -f "$path" ]]; then - curl -fL "$url" -o "$path" + local actual_sha="" + if [[ -f "$path" ]]; then + actual_sha="$(shasum -a 256 "$path" | awk '{print $1}')" + if [[ "$actual_sha" == "$expected_sha" ]]; then + return 0 + fi + echo "warning: refetching $path (sha256 mismatch)" >&2 fi - local actual_sha + curl -fL --retry 3 "$url" -o "$path" actual_sha="$(shasum -a 256 "$path" | awk '{print $1}')" if [[ "$actual_sha" != "$expected_sha" ]]; then echo "error: sha256 mismatch for $path: $actual_sha != $expected_sha" >&2 @@ -149,6 +156,17 @@ if $FETCH_ONLY; then exit 0 fi +MIMI_FULL_N_Q="$($PYTHON_BIN - "$MOSHI_CONFIG" <<'PY' +import json +import sys + +value = json.load(open(sys.argv[1], encoding="utf-8")).get("n_q") +if not isinstance(value, int) or value <= 0: + raise SystemExit("Mimi n_q must be a positive integer") +print(value) +PY +)" + convert_if_needed() { local source="$1" local output="$2" @@ -179,8 +197,12 @@ convert_if_needed() { } convert_if_needed "$MOSHI_MODEL" "$MOSHI_MODEL_EMEL" \ - --config "$MOSHI_CONFIG" --tokenizer "$TOKENIZER_MODEL" -convert_if_needed "$MIMI_MODEL" "$MIMI_MODEL_EMEL" --config "$MOSHI_CONFIG" + --config "$MOSHI_CONFIG" --inference-config "$MOSHI_INFERENCE_CONFIG" \ + --tokenizer "$TOKENIZER_MODEL" +convert_if_needed "$MIMI_MODEL" "$MIMI_MODEL_EMEL" \ + --config "$MOSHI_CONFIG" --mimi-n-q "$MIMI_FULL_N_Q" +convert_if_needed "$MIMI_MODEL" "$MIMI_MODEL_PERSONAPLEX_EMEL" \ + --config "$MOSHI_CONFIG" --inference-config "$MOSHI_INFERENCE_CONFIG" convert_if_needed "$VOICE_MODEL" "$VOICE_MODEL_EMEL" echo "EMEL_MOSHI_CPP_SOURCE=$REFERENCE_DIR" @@ -188,6 +210,7 @@ echo "EMEL_MOSHI_REFERENCE_MODEL=$MOSHI_MODEL" echo "EMEL_MOSHI_REFERENCE_MODEL_EMEL=$MOSHI_MODEL_EMEL" echo "EMEL_MIMI_REFERENCE_MODEL=$MIMI_MODEL" echo "EMEL_MIMI_REFERENCE_MODEL_EMEL=$MIMI_MODEL_EMEL" +echo "EMEL_MIMI_PERSONAPLEX_MODEL_EMEL=$MIMI_MODEL_PERSONAPLEX_EMEL" echo "EMEL_MOSHI_TOKENIZER_MODEL=$TOKENIZER_MODEL" echo "EMEL_MOSHI_VOICE_MODEL=$VOICE_MODEL" echo "EMEL_MOSHI_VOICE_MODEL_EMEL=$VOICE_MODEL_EMEL" diff --git a/scripts/setup_personaplex_mlx_reference.sh b/scripts/setup_personaplex_mlx_reference.sh index 070d46ff..13c3b86f 100755 --- a/scripts/setup_personaplex_mlx_reference.sh +++ b/scripts/setup_personaplex_mlx_reference.sh @@ -131,10 +131,20 @@ if [[ ! -f "$MIMI_MODEL_EMEL" || "$MIMI_MODEL" -nt "$MIMI_MODEL_EMEL" || "$CONVERTER" -nt "$MIMI_MODEL_EMEL" ]]; then # Use the interpreter discovered by the version check above: hosts that only # ship python3.12/python3.13 (no python3 shim) must convert with it too. + MIMI_FULL_N_Q="$($PYTHON_BIN - "$MOSHI_CONFIG" <<'PY' +import json +import sys + +value = json.load(open(sys.argv[1], encoding="utf-8")).get("n_q") +if not isinstance(value, int) or value <= 0: + raise SystemExit("Mimi n_q must be a positive integer") +print(value) +PY +)" "$PYTHON_BIN" "$ROOT_DIR/tools/bench/moshi_gguf_convert.py" \ --source "$MIMI_MODEL" --output "$MIMI_MODEL_EMEL" \ --manifest "${MIMI_MODEL_EMEL%.gguf}.manifest.json" \ - --config "$MOSHI_CONFIG" + --config "$MOSHI_CONFIG" --mimi-n-q "$MIMI_FULL_N_Q" fi cat > "$DRIVER_SHIM" < + +#include "emel/speech/generator/moshi/personaplex/session/context.hpp" +#include "emel/speech/generator/moshi/personaplex/session/events.hpp" + +namespace emel::speech::generator::moshi::personaplex::session::action { + +namespace detail_ns { + +inline emel::error::type to_error(const error::code value) noexcept { + return emel::error::cast(value); +} + +template +void effect_store_error(const runtime_event_type &runtime_ev, + const error::code value) noexcept { + runtime_ev.ctx.err = to_error(value); + runtime_ev.request.error_out = runtime_ev.ctx.err; +} + +} // namespace detail_ns + +struct effect_initialize_encoder { + static void effect_capture_codec_initialize( + event::initialize_ctx &runtime, + const mimi::events::initialize_done &done) noexcept { + runtime.frame_samples = done.frame_samples; + runtime.mimi_n_q = done.n_q; + } + + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + mimi::event::initialize request{ + runtime_ev.request.mimi_model, + runtime_ev.request.encoder_storage.prepared, + runtime_ev.request.encoder_storage.state, + runtime_ev.request.encoder_storage.workspace, + runtime_ev.request.encoder_storage.frame}; + request.error_out = &runtime_ev.ctx.child_err; + request.on_done = + emel::callback::from< + event::initialize_ctx, + &effect_initialize_encoder::effect_capture_codec_initialize>( + runtime_ev.ctx); + runtime_ev.ctx.child_accepted = ctx.encoder.process_event(request); + } +}; + +struct effect_initialize_decoder { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + mimi::event::initialize request{ + runtime_ev.request.mimi_model, + runtime_ev.request.decoder_storage.prepared, + runtime_ev.request.decoder_storage.state, + runtime_ev.request.decoder_storage.workspace, + runtime_ev.request.decoder_storage.frame}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = ctx.decoder.process_event(request); + } +}; + +struct effect_initialize_executor { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + executor::event::initialize request{runtime_ev.request.lm_model}; + request.sampling_enabled = runtime_ev.request.sampling.enabled; + request.sampling_consume_forced_text = + runtime_ev.request.sampling.consume_forced_text; + request.sampling_audio_temperature = + runtime_ev.request.sampling.audio_temperature; + request.sampling_text_temperature = + runtime_ev.request.sampling.text_temperature; + request.sampling_audio_top_k = runtime_ev.request.sampling.audio_top_k; + request.sampling_text_top_k = runtime_ev.request.sampling.text_top_k; + request.sampling_seed = runtime_ev.request.sampling.seed; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = ctx.graph_executor.process_event(request); + } +}; + +struct effect_initialize_generator { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + moshi::event::initialize request{runtime_ev.request.lm_model}; + request.max_blocks = runtime_ev.request.max_blocks; + request.block_tokens = runtime_ev.request.block_tokens; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); + } +}; + +struct effect_load_voice { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + moshi::event::load_voice request{runtime_ev.request.voice_model}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); + } +}; + +struct effect_publish_initialize_done { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + ctx.frame_samples = runtime_ev.ctx.frame_samples; + ctx.public_n_q = runtime_ev.ctx.mimi_n_q; + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_fail_initialize_invalid { + void operator()(const event::initialize_run &runtime_ev, + context &) const noexcept { + detail_ns::effect_store_error(runtime_ev, error::invalid_request); + } +}; + +template struct effect_fail_initialize_child { + void operator()(const event::initialize_run &runtime_ev, + context &) const noexcept { + detail_ns::effect_store_error(runtime_ev, error_code); + } +}; + +struct effect_prefill_voice { + void operator()(const event::advance_voice_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.graph_err = 0; + runtime_ev.ctx.complete = false; + runtime_ev.ctx.remaining_frames = -1; + moshi::event::prefill_voice request{}; + request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; + request.complete_out = &runtime_ev.ctx.complete; + request.remaining_frames_out = &runtime_ev.ctx.remaining_frames; + runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); + } +}; + +struct effect_begin_prompt { + void operator()(const event::advance_voice_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + moshi::event::begin_personaplex_prompt request{}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); + } +}; + +struct effect_publish_advance_voice_done { + void operator()(const event::advance_voice_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_fail_advance_voice { + void operator()(const event::advance_voice_run &runtime_ev, + context &) const noexcept { + detail_ns::effect_store_error(runtime_ev, error_code); + } +}; + +struct effect_prefill_prompt { + void operator()(const event::advance_prompt_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.graph_err = 0; + runtime_ev.ctx.complete = false; + runtime_ev.ctx.remaining_frames = -1; + moshi::event::prefill_personaplex_prompt request{}; + request.text_token = runtime_ev.request.text_token; + request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; + request.complete_out = &runtime_ev.ctx.complete; + request.remaining_frames_out = &runtime_ev.ctx.remaining_frames; + runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); + } +}; + +struct effect_publish_advance_prompt_done { + void operator()(const event::advance_prompt_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_fail_advance_prompt { + void operator()(const event::advance_prompt_run &runtime_ev, + context &) const noexcept { + detail_ns::effect_store_error(runtime_ev, error_code); + } +}; + +template struct effect_encode_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + mimi::event::encode_frame request{ + runtime_ev.request.payload.pcm, + runtime_ev.request.payload.input_codes_out.first( + static_cast(ctx.public_n_q))}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = ctx.encoder.process_event(request); + } +}; + +template struct effect_generate_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.graph_err = 0; + runtime_ev.ctx.produced = false; + std::fill_n(runtime_ev.request.payload.output_codes_out.data(), + static_cast(ctx.public_n_q), -1); + moshi::event::step request{ + runtime_ev.request.payload.input_codes_out.first( + static_cast(ctx.public_n_q)), + runtime_ev.request.payload.output_codes_out.first( + static_cast(ctx.public_n_q)), + runtime_ev.request.payload.text_token_out}; + request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; + request.produced_out = &runtime_ev.ctx.produced; + runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); + } +}; + +template struct effect_decode_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + mimi::event::decode_frame request{ + runtime_ev.request.payload.output_codes_out.first( + static_cast(ctx.public_n_q)), + runtime_ev.request.payload.pcm_out}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = ctx.decoder.process_event(request); + } +}; + +template struct effect_publish_frame_done { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + runtime_ev.request.payload.produced_out = runtime_ev.ctx.produced; + } +}; + +template +struct effect_fail_frame { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + detail_ns::effect_store_error(runtime_ev, error_code); + runtime_ev.request.payload.produced_out = false; + } +}; + +struct effect_publish_begin_flush_done { + void operator()(const event::begin_flush_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_fail_begin_flush_invalid { + void operator()(const event::begin_flush_run &runtime_ev, + context &) const noexcept { + detail_ns::effect_store_error(runtime_ev, error::invalid_request); + } +}; + +struct effect_publish_finish_done { + void operator()(const event::finish_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_fail_finish_invalid { + void operator()(const event::finish_run &runtime_ev, + context &) const noexcept { + detail_ns::effect_store_error(runtime_ev, error::invalid_request); + } +}; + +struct effect_mark_unexpected { + template + void operator()(const unexpected_event_type &runtime_ev, + context &) const noexcept { + if constexpr (requires { + runtime_ev.ctx.err; + runtime_ev.request.error_out; + }) { + runtime_ev.ctx.err = detail_ns::to_error(error::unexpected_event); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } + } +}; + +} // namespace emel::speech::generator::moshi::personaplex::session::action diff --git a/src/emel/speech/generator/moshi/personaplex/session/any.hpp b/src/emel/speech/generator/moshi/personaplex/session/any.hpp new file mode 100644 index 00000000..70e124e0 --- /dev/null +++ b/src/emel/speech/generator/moshi/personaplex/session/any.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "emel/speech/generator/moshi/personaplex/session/sm.hpp" + +namespace emel::speech::generator::moshi::personaplex::session { + +using dependencies = action::dependencies; +using PersonaPlexSession = sm; + +} // namespace emel::speech::generator::moshi::personaplex::session diff --git a/src/emel/speech/generator/moshi/personaplex/session/context.hpp b/src/emel/speech/generator/moshi/personaplex/session/context.hpp new file mode 100644 index 00000000..7e14b196 --- /dev/null +++ b/src/emel/speech/generator/moshi/personaplex/session/context.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include "emel/memory/hybrid/context.hpp" +#include "emel/speech/codec/mimi/any.hpp" +#include "emel/speech/generator/moshi/any.hpp" +#include "emel/speech/generator/moshi/executor/any.hpp" + +namespace emel::speech::generator::moshi::personaplex::session::action { + +namespace mimi = emel::speech::codec::mimi; +namespace moshi = emel::speech::generator::moshi; +namespace executor = emel::speech::generator::moshi::executor; + +struct dependencies { + executor::detail::temporal_kv_view temporal_kv = {}; + executor::detail::depformer_kv_view depformer_kv = {}; + emel::memory::hybrid::kv_binding generator_memory = {}; +}; + +struct context { + explicit context(const dependencies &deps) + : temporal_kv(deps.temporal_kv), depformer_kv(deps.depformer_kv), + graph_executor(executor::bind_kv_caches( + executor::bind_temporal_kv_cache(this, bind_temporal_cache), + executor::bind_depformer_kv_cache(this, bind_depformer_cache))), + generator(deps.generator_memory, + moshi::action::bind_graph_executor( + &graph_executor, executor::dispatch_graph_step)) {} + + static bool + bind_temporal_cache(void *context_ptr, const emel::model::data &, + const emel::memory::view::snapshot &, int32_t, + executor::detail::temporal_kv_view &view) noexcept { + view = static_cast(context_ptr)->temporal_kv; + return true; + } + + static bool + bind_depformer_cache(void *context_ptr, const emel::model::data &, + const emel::memory::view::snapshot &, int32_t, + executor::detail::depformer_kv_view &view) noexcept { + view = static_cast(context_ptr)->depformer_kv; + return true; + } + + executor::detail::temporal_kv_view temporal_kv = {}; + executor::detail::depformer_kv_view depformer_kv = {}; + int32_t frame_samples = 0; + int32_t public_n_q = 0; + mimi::sm encoder = {}; + mimi::sm decoder = {}; + executor::sm graph_executor; + moshi::sm generator; +}; + +} // namespace emel::speech::generator::moshi::personaplex::session::action diff --git a/src/emel/speech/generator/moshi/personaplex/session/errors.hpp b/src/emel/speech/generator/moshi/personaplex/session/errors.hpp new file mode 100644 index 00000000..e36ecdf1 --- /dev/null +++ b/src/emel/speech/generator/moshi/personaplex/session/errors.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "emel/error/error.hpp" + +namespace emel::speech::generator::moshi::personaplex::session::error { + +enum code : emel::error::type { + none = 0, + invalid_request, + codec_initialize_failed, + executor_initialize_failed, + generator_initialize_failed, + voice_load_failed, + voice_prefill_failed, + prompt_begin_failed, + prompt_prefill_failed, + encode_failed, + generate_failed, + decode_failed, + unexpected_event, +}; + +} // namespace emel::speech::generator::moshi::personaplex::session::error diff --git a/src/emel/speech/generator/moshi/personaplex/session/events.hpp b/src/emel/speech/generator/moshi/personaplex/session/events.hpp new file mode 100644 index 00000000..f8d74586 --- /dev/null +++ b/src/emel/speech/generator/moshi/personaplex/session/events.hpp @@ -0,0 +1,217 @@ +#pragma once + +#include +#include + +#include "emel/error/error.hpp" +#include "emel/model/data.hpp" +#include "emel/speech/generator/moshi/personaplex/session/errors.hpp" + +namespace emel::speech::generator::moshi::personaplex::session::events { + +struct initialize_done; +struct initialize_error; +struct advance_voice_done; +struct advance_voice_error; +struct advance_prompt_done; +struct advance_prompt_error; +struct live_frame_done; +struct live_frame_error; +struct begin_flush_done; +struct begin_flush_error; +struct flush_frame_done; +struct flush_frame_error; +struct finish_done; +struct finish_error; + +} // namespace emel::speech::generator::moshi::personaplex::session::events + +namespace emel::speech::generator::moshi::personaplex::session::event { + +struct codec_storage { + std::span prepared = {}; + std::span state = {}; + std::span workspace = {}; + std::span frame = {}; +}; + +struct sampling_config { + bool enabled = false; + bool consume_forced_text = false; + float audio_temperature = 0.0f; + float text_temperature = 0.0f; + int32_t audio_top_k = 0; + int32_t text_top_k = 0; + uint32_t seed = 0; +}; + +struct initialize { + const emel::model::data &mimi_model; + const emel::model::data &lm_model; + const emel::model::data &voice_model; + codec_storage encoder_storage = {}; + codec_storage decoder_storage = {}; + sampling_config sampling = {}; + int32_t max_blocks = 0; + int32_t block_tokens = 0; + emel::error::type &error_out; +}; + +struct advance_voice { + emel::error::type &error_out; +}; + +struct advance_prompt { + int32_t text_token = -1; + emel::error::type &error_out; +}; + +struct frame_payload { + std::span pcm = {}; + std::span input_codes_out = {}; + std::span output_codes_out = {}; + int32_t &text_token_out; + bool &produced_out; + std::span pcm_out = {}; +}; + +struct live_frame { + frame_payload payload; + emel::error::type &error_out; +}; + +struct begin_flush { + emel::error::type &error_out; +}; + +struct flush_frame { + frame_payload payload; + emel::error::type &error_out; +}; + +struct finish { + emel::error::type &error_out; +}; + +struct initialize_ctx { + emel::error::type err = emel::error::cast(error::none); + emel::error::type child_err = 0; + emel::error::type graph_err = 0; + bool child_accepted = false; + int32_t frame_samples = 0; + int32_t mimi_n_q = 0; +}; + +struct phase_ctx { + emel::error::type err = emel::error::cast(error::none); + emel::error::type child_err = 0; + emel::error::type graph_err = 0; + bool child_accepted = false; + bool complete = false; + int32_t remaining_frames = -1; +}; + +struct frame_ctx { + emel::error::type err = emel::error::cast(error::none); + emel::error::type child_err = 0; + emel::error::type graph_err = 0; + bool child_accepted = false; + bool produced = false; +}; + +struct simple_ctx { + emel::error::type err = emel::error::cast(error::none); +}; + +struct initialize_run { + const initialize &request; + initialize_ctx &ctx; +}; +struct advance_voice_run { + const advance_voice &request; + phase_ctx &ctx; +}; +struct advance_prompt_run { + const advance_prompt &request; + phase_ctx &ctx; +}; +struct live_frame_run { + const live_frame &request; + frame_ctx &ctx; +}; +struct begin_flush_run { + const begin_flush &request; + simple_ctx &ctx; +}; +struct flush_frame_run { + const flush_frame &request; + frame_ctx &ctx; +}; +struct finish_run { + const finish &request; + simple_ctx &ctx; +}; + +} // namespace emel::speech::generator::moshi::personaplex::session::event + +namespace emel::speech::generator::moshi::personaplex::session::events { + +struct initialize_done { + const event::initialize *request = nullptr; + int32_t frame_samples = 0; + int32_t n_q = 0; +}; +struct initialize_error { + const event::initialize *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; +struct advance_voice_done { + const event::advance_voice *request = nullptr; + bool complete = false; + int32_t remaining_frames = -1; +}; +struct advance_voice_error { + const event::advance_voice *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; +struct advance_prompt_done { + const event::advance_prompt *request = nullptr; + bool complete = false; + int32_t remaining_frames = -1; +}; +struct advance_prompt_error { + const event::advance_prompt *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; +struct live_frame_done { + const event::live_frame *request = nullptr; + bool produced = false; +}; +struct live_frame_error { + const event::live_frame *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; +struct begin_flush_done { + const event::begin_flush *request = nullptr; +}; +struct begin_flush_error { + const event::begin_flush *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; +struct flush_frame_done { + const event::flush_frame *request = nullptr; + bool produced = false; +}; +struct flush_frame_error { + const event::flush_frame *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; +struct finish_done { + const event::finish *request = nullptr; +}; +struct finish_error { + const event::finish *request = nullptr; + emel::error::type err = emel::error::cast(error::none); +}; + +} // namespace emel::speech::generator::moshi::personaplex::session::events diff --git a/src/emel/speech/generator/moshi/personaplex/session/guards.hpp b/src/emel/speech/generator/moshi/personaplex/session/guards.hpp new file mode 100644 index 00000000..694227c5 --- /dev/null +++ b/src/emel/speech/generator/moshi/personaplex/session/guards.hpp @@ -0,0 +1,188 @@ +#pragma once + +#include +#include + +#include "emel/speech/generator/moshi/personaplex/session/context.hpp" +#include "emel/speech/generator/moshi/personaplex/session/events.hpp" + +namespace emel::speech::generator::moshi::personaplex::session::guard { + +struct guard_initialize_request_valid { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &request = runtime_ev.request; + const auto &lm = request.lm_model.moshi_lm; + const auto &mimi = request.mimi_model.mimi; + if (lm.num_layers <= 0 || lm.context <= 0 || lm.dim <= 0 || + lm.depformer_num_layers <= 0 || lm.depformer_context <= 0 || + lm.depformer_dim <= 0 || lm.inference_dep_q <= 0 || mimi.n_q <= 0 || + lm.card <= 0 || mimi.card <= 0) { + return false; + } + const size_t temporal_layers = static_cast(lm.num_layers); + const size_t temporal_context = static_cast(lm.context); + const size_t depformer_layers = + static_cast(lm.depformer_num_layers); + const size_t depformer_context = static_cast(lm.depformer_context); + if (temporal_context > + std::numeric_limits::max() / temporal_layers || + static_cast(lm.dim) > + std::numeric_limits::max() / + (temporal_layers * temporal_context) || + depformer_context > + std::numeric_limits::max() / depformer_layers || + static_cast(lm.depformer_dim) > + std::numeric_limits::max() / + (depformer_layers * depformer_context)) { + return false; + } + const size_t temporal_elements = + temporal_layers * temporal_context * static_cast(lm.dim); + const size_t depformer_elements = depformer_layers * depformer_context * + static_cast(lm.depformer_dim); + return request.sampling.enabled && request.sampling.consume_forced_text && + request.sampling.audio_temperature > 0.0f && + request.sampling.text_temperature > 0.0f && + request.sampling.audio_top_k > 0 && + request.sampling.text_top_k > 0 && request.sampling.seed != 0u && + request.max_blocks > 0 && request.block_tokens > 0 && + lm.inference_dep_q == mimi.n_q && lm.card == mimi.card && + ctx.temporal_kv.key_cache.data() != nullptr && + ctx.temporal_kv.value_cache.data() != nullptr && + ctx.temporal_kv.offset != nullptr && + ctx.temporal_kv.key_cache.size() >= temporal_elements && + ctx.temporal_kv.value_cache.size() >= temporal_elements && + ctx.temporal_kv.layer_cache_offsets.size() >= + static_cast(lm.num_layers) && + ctx.temporal_kv.layer_count == lm.num_layers && + ctx.temporal_kv.position_capacity == lm.context && + ctx.temporal_kv.block_tokens > 0 && + ctx.temporal_kv.kv_dim == lm.dim && + ctx.depformer_kv.key_cache.data() != nullptr && + ctx.depformer_kv.value_cache.data() != nullptr && + ctx.depformer_kv.offset != nullptr && + ctx.depformer_kv.key_cache.size() >= depformer_elements && + ctx.depformer_kv.value_cache.size() >= depformer_elements && + ctx.depformer_kv.layer_cache_offsets.size() >= + static_cast(lm.depformer_num_layers) && + ctx.depformer_kv.layer_count == lm.depformer_num_layers && + ctx.depformer_kv.position_capacity == lm.depformer_context && + ctx.depformer_kv.block_tokens > 0 && + ctx.depformer_kv.kv_dim == lm.depformer_dim; + } +}; + +struct guard_initialize_request_invalid { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_initialize_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_encoder_initialize_succeeded { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.frame_samples > 0 && runtime_ev.ctx.mimi_n_q > 0 && + runtime_ev.ctx.mimi_n_q == + runtime_ev.request.lm_model.moshi_lm.inference_dep_q; + } +}; + +struct guard_encoder_initialize_failed { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_encoder_initialize_succeeded{}(runtime_ev, ctx); + } +}; + +template struct guard_child_succeeded { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0; + } +}; + +template struct guard_child_failed { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_child_succeeded{}(runtime_ev, ctx); + } +}; + +template struct guard_phase_succeeded_incomplete { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && !runtime_ev.ctx.complete; + } +}; + +template struct guard_phase_succeeded_complete { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && runtime_ev.ctx.complete; + } +}; + +template struct guard_phase_failed { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.ctx.child_accepted || runtime_ev.ctx.child_err != 0 || + runtime_ev.ctx.graph_err != 0; + } +}; + +template struct guard_frame_request_valid { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + const auto &request = runtime_ev.request; + const auto &payload = request.payload; + return payload.pcm.data() != nullptr && + payload.input_codes_out.data() != nullptr && + payload.output_codes_out.data() != nullptr && + payload.pcm_out.data() != nullptr && + payload.pcm.size() == static_cast(ctx.frame_samples) && + payload.input_codes_out.size() >= + static_cast(ctx.public_n_q) && + payload.output_codes_out.size() >= + static_cast(ctx.public_n_q) && + payload.pcm_out.size() >= static_cast(ctx.frame_samples); + } +}; + +template struct guard_frame_request_invalid { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_frame_request_valid{}(runtime_ev, ctx); + } +}; + +template struct guard_frame_generated_and_produced { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && runtime_ev.ctx.produced; + } +}; + +template +struct guard_frame_generated_without_output { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && !runtime_ev.ctx.produced; + } +}; + +template struct guard_frame_generate_failed { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.ctx.child_accepted || runtime_ev.ctx.child_err != 0 || + runtime_ev.ctx.graph_err != 0; + } +}; + +} // namespace emel::speech::generator::moshi::personaplex::session::guard diff --git a/src/emel/speech/generator/moshi/personaplex/session/sm.hpp b/src/emel/speech/generator/moshi/personaplex/session/sm.hpp new file mode 100644 index 00000000..ec270561 --- /dev/null +++ b/src/emel/speech/generator/moshi/personaplex/session/sm.hpp @@ -0,0 +1,297 @@ +#pragma once +// benchmark: designed + +#include + +#include "emel/sm.hpp" +#include "emel/speech/generator/moshi/personaplex/session/actions.hpp" +#include "emel/speech/generator/moshi/personaplex/session/context.hpp" +#include "emel/speech/generator/moshi/personaplex/session/events.hpp" +#include "emel/speech/generator/moshi/personaplex/session/guards.hpp" + +namespace emel::speech::generator::moshi::personaplex::session { + +struct state_uninitialized {}; +struct state_initialize_encoder_result {}; +struct state_initialize_decoder_result {}; +struct state_initialize_executor_result {}; +struct state_initialize_generator_result {}; +struct state_load_voice_result {}; +struct state_voice_prefill {}; +struct state_voice_prefill_result {}; +struct state_prompt_begin_result {}; +struct state_prompt_prefill {}; +struct state_prompt_prefill_result {}; +struct state_live {}; +struct state_live_encode_result {}; +struct state_live_generate_result {}; +struct state_live_decode_result {}; +struct state_flush {}; +struct state_flush_encode_result {}; +struct state_flush_generate_result {}; +struct state_flush_decode_result {}; +struct state_done {}; +struct state_failed {}; + +struct model { + auto operator()() const { + namespace sml = stateforward::sml; + using init_run = event::initialize_run; + using voice_run = event::advance_voice_run; + using prompt_run = event::advance_prompt_run; + using live_run = event::live_frame_run; + using begin_flush_run = event::begin_flush_run; + using flush_run = event::flush_frame_run; + using finish_run = event::finish_run; + + // clang-format off + return sml::make_transition_table( + //------------------------------------------------------------------------------// + // Initialize every child actor in deterministic RTC order. + sml::state <= *sml::state + + sml::event [ guard::guard_initialize_request_valid{} ] + / action::effect_initialize_encoder{} + , sml::state <= sml::state + + sml::event [ guard::guard_initialize_request_invalid{} ] + / action::effect_fail_initialize_invalid{} + , sml::state <= sml::state + + sml::completion [ guard::guard_encoder_initialize_succeeded{} ] + / action::effect_initialize_decoder{} + , sml::state <= sml::state + + sml::completion [ guard::guard_encoder_initialize_failed{} ] + / action::effect_fail_initialize_child{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_initialize_executor{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_initialize_child{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_initialize_generator{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_initialize_child{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_load_voice{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_initialize_child{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_publish_initialize_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_initialize_child{} + + //------------------------------------------------------------------------------// + // Voice and empty/system prompt prefill phases. + , sml::state <= sml::state + + sml::event / action::effect_prefill_voice{} + , sml::state <= sml::state + + sml::completion [ guard::guard_phase_succeeded_incomplete{} ] + / action::effect_publish_advance_voice_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_phase_succeeded_complete{} ] + / action::effect_begin_prompt{} + , sml::state <= sml::state + + sml::completion [ guard::guard_phase_failed{} ] + / action::effect_fail_advance_voice{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_publish_advance_voice_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_advance_voice{} + , sml::state <= sml::state + + sml::event / action::effect_prefill_prompt{} + , sml::state <= sml::state + + sml::completion [ guard::guard_phase_succeeded_incomplete{} ] + / action::effect_publish_advance_prompt_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_phase_succeeded_complete{} ] + / action::effect_publish_advance_prompt_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_phase_failed{} ] + / action::effect_fail_advance_prompt{} + + //------------------------------------------------------------------------------// + // Live input frames. Produced/decode selection is explicit. + , sml::state <= sml::state + + sml::event [ guard::guard_frame_request_valid{} ] + / action::effect_encode_frame{} + , sml::state <= sml::state + + sml::event [ guard::guard_frame_request_invalid{} ] + / action::effect_fail_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_generate_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_generated_and_produced{} ] + / action::effect_decode_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_generated_without_output{} ] + / action::effect_publish_frame_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_generate_failed{} ] + / action::effect_fail_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_publish_frame_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_frame{} + + //------------------------------------------------------------------------------// + // Explicit silence flush and terminal phases. + , sml::state <= sml::state + + sml::event / action::effect_publish_begin_flush_done{} + , sml::state <= sml::state + + sml::event [ guard::guard_frame_request_valid{} ] + / action::effect_encode_frame{} + , sml::state <= sml::state + + sml::event [ guard::guard_frame_request_invalid{} ] + / action::effect_fail_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_generate_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_generated_and_produced{} ] + / action::effect_decode_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_generated_without_output{} ] + / action::effect_publish_frame_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_generate_failed{} ] + / action::effect_fail_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_publish_frame_done{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_frame{} + , sml::state <= sml::state + + sml::event / action::effect_publish_finish_done{} + + //------------------------------------------------------------------------------// + // Every external event outside its modeled phase is explicit. + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + ); + // clang-format on + } +}; + +struct sm : public emel::sm { + using base_type = emel::sm; + using base_type::is; + using base_type::visit_current_states; + + explicit sm(const action::dependencies &deps) + : base_type(std::in_place, deps) {} + + sm(const sm &) = delete; + sm &operator=(const sm &) = delete; + sm(sm &&) = delete; + sm &operator=(sm &&) = delete; + + bool process_event(const event::initialize &request) { + event::initialize_ctx ctx{}; + event::initialize_run runtime_ev{request, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::advance_voice &request) { + event::phase_ctx ctx{}; + event::advance_voice_run runtime_ev{request, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::advance_prompt &request) { + event::phase_ctx ctx{}; + event::advance_prompt_run runtime_ev{request, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::live_frame &request) { + event::frame_ctx ctx{}; + event::live_frame_run runtime_ev{request, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::begin_flush &request) { + event::simple_ctx ctx{}; + event::begin_flush_run runtime_ev{request, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::flush_frame &request) { + event::frame_ctx ctx{}; + event::flush_frame_run runtime_ev{request, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::finish &request) { + event::simple_ctx ctx{}; + event::finish_run runtime_ev{request, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } +}; + +using Session = sm; + +} // namespace emel::speech::generator::moshi::personaplex::session diff --git a/tests/speech/generator/moshi_fixture.hpp b/tests/speech/generator/moshi_fixture.hpp new file mode 100644 index 00000000..fce5eb4c --- /dev/null +++ b/tests/speech/generator/moshi_fixture.hpp @@ -0,0 +1,136 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "emel/gguf/loader/detail.hpp" +#include "emel/gguf/loader/events.hpp" +#include "emel/gguf/loader/sm.hpp" +#include "emel/model/detail.hpp" + +namespace emel::speech::generator::moshi::test { + +struct loaded_fixture { + std::vector file_bytes = {}; + std::vector kv_arena = {}; + std::vector kv_entries = {}; + std::unique_ptr model = {}; + + emel::model::detail::kv_binding binding() const { + return emel::model::detail::kv_binding{ + .arena = std::span{kv_arena}, + .entries = std::span{kv_entries}, + }; + } +}; + +inline std::filesystem::path repo_root() { +#ifdef EMEL_TEST_REPO_ROOT + return std::filesystem::path{EMEL_TEST_REPO_ROOT}; +#else + return std::filesystem::current_path(); +#endif +} + +inline std::filesystem::path fixture_path(const std::string_view name) { + return repo_root() / "tests" / "models" / std::string{name}; +} + +inline std::vector +read_binary_file(const std::filesystem::path &path) { + std::ifstream file{path, std::ios::binary}; + REQUIRE(file.good()); + file.seekg(0, std::ios::end); + const std::streamoff size = file.tellg(); + REQUIRE(size > 0); + std::vector bytes(static_cast(size)); + file.seekg(0, std::ios::beg); + file.read(reinterpret_cast(bytes.data()), size); + REQUIRE(file.good()); + return bytes; +} + +inline void noop_probe_done(const emel::gguf::loader::events::probe_done &) {} +inline void noop_probe_error(const emel::gguf::loader::events::probe_error &) {} +inline void noop_bind_done(const emel::gguf::loader::events::bind_done &) {} +inline void noop_bind_error(const emel::gguf::loader::events::bind_error &) {} +inline void noop_parse_done(const emel::gguf::loader::events::parse_done &) {} +inline void noop_parse_error(const emel::gguf::loader::events::parse_error &) {} + +inline void +materialize_tensor_names_from_file(emel::model::data &model, + const std::vector &file) { + model.name_bytes_used = 0; + for (uint32_t index = 0; index < model.n_tensors; ++index) { + auto &tensor = model.tensors[index]; + const size_t source_offset = static_cast(tensor.name_offset); + const size_t length = static_cast(tensor.name_length); + REQUIRE(source_offset + length <= file.size()); + REQUIRE(static_cast(model.name_bytes_used) + length <= + model.name_storage.size()); + std::copy_n(file.data() + source_offset, length, + model.name_storage.data() + model.name_bytes_used); + tensor.name_offset = model.name_bytes_used; + model.name_bytes_used += static_cast(length); + } +} + +inline loaded_fixture load_fixture_or_skip(const std::string_view name) { + const auto path = fixture_path(name); + if (!std::filesystem::exists(path)) { + MESSAGE("skipping Moshi fixture test because fixture is missing: " + << path.string()); + return {}; + } + + loaded_fixture loaded{}; + loaded.model = std::make_unique(); + loaded.file_bytes = read_binary_file(path); + + emel::gguf::loader::sm loader{}; + emel::gguf::loader::requirements requirements{}; + REQUIRE(loader.process_event(emel::gguf::loader::event::probe{ + std::span{loaded.file_bytes}, + requirements, + emel::gguf::loader::event::probe_done_fn::from<&noop_probe_done>(), + emel::gguf::loader::event::probe_error_fn::from<&noop_probe_error>(), + })); + + const uint64_t arena_bytes = + emel::gguf::loader::detail::required_kv_arena_bytes(requirements); + REQUIRE(arena_bytes != UINT64_MAX); + loaded.kv_arena.resize(static_cast(arena_bytes)); + loaded.kv_entries.resize(requirements.kv_count); + loaded.model->n_tensors = requirements.tensor_count; + + REQUIRE(loader.process_event(emel::gguf::loader::event::bind_storage{ + std::span{loaded.kv_arena}, + std::span{loaded.kv_entries}, + std::span{loaded.model->tensors.data(), + loaded.model->n_tensors}, + emel::gguf::loader::event::bind_done_fn::from<&noop_bind_done>(), + emel::gguf::loader::event::bind_error_fn::from<&noop_bind_error>(), + })); + REQUIRE(loader.process_event(emel::gguf::loader::event::parse{ + std::span{loaded.file_bytes}, + emel::gguf::loader::event::parse_done_fn::from<&noop_parse_done>(), + emel::gguf::loader::event::parse_error_fn::from<&noop_parse_error>(), + })); + REQUIRE(emel::model::detail::load_hparams_from_gguf(loaded.binding(), + *loaded.model)); + loaded.model->weights_data = loaded.file_bytes.data(); + loaded.model->weights_size = loaded.file_bytes.size(); + materialize_tensor_names_from_file(*loaded.model, loaded.file_bytes); + return loaded; +} + +} // namespace emel::speech::generator::moshi::test diff --git a/tests/speech/generator/moshi_lifecycle_tests.cpp b/tests/speech/generator/moshi_lifecycle_tests.cpp index f372b9a9..9e98d242 100644 --- a/tests/speech/generator/moshi_lifecycle_tests.cpp +++ b/tests/speech/generator/moshi_lifecycle_tests.cpp @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include #include #include @@ -13,14 +11,11 @@ #include #include "../../memory/recording_kv_actor.hpp" -#include "emel/gguf/loader/detail.hpp" -#include "emel/gguf/loader/events.hpp" -#include "emel/gguf/loader/sm.hpp" -#include "emel/model/detail.hpp" #include "emel/model/moshi/detail.hpp" #include "emel/speech/codec/mimi/any.hpp" #include "emel/speech/generator/moshi/any.hpp" #include "emel/speech/generator/moshi/executor/any.hpp" +#include "moshi_fixture.hpp" namespace { @@ -28,6 +23,9 @@ namespace moshi = emel::speech::generator::moshi; namespace moshi_executor = emel::speech::generator::moshi::executor; namespace mimi = emel::speech::codec::mimi; namespace model_moshi = emel::model::moshi::detail; +using emel::speech::generator::moshi::test::load_fixture_or_skip; +using emel::speech::generator::moshi::test::read_binary_file; +using emel::speech::generator::moshi::test::repo_root; inline constexpr emel::error::type k_no_error = emel::error::cast(moshi::error::none); @@ -35,38 +33,6 @@ inline constexpr emel::error::type k_no_error = int32_t g_mimi_frame_samples = 0; int32_t g_mimi_n_q = 0; -std::filesystem::path repo_root() { -#ifdef EMEL_TEST_REPO_ROOT - return std::filesystem::path{EMEL_TEST_REPO_ROOT}; -#else - return std::filesystem::current_path(); -#endif -} - -std::filesystem::path moshi_fixture_path(const std::string_view name) { - return repo_root() / "tests" / "models" / std::string{name}; -} - -std::vector read_binary_file(const std::filesystem::path &path) { - std::ifstream file{path, std::ios::binary}; - REQUIRE(file.good()); - file.seekg(0, std::ios::end); - const std::streamoff size = file.tellg(); - REQUIRE(size > 0); - std::vector bytes(static_cast(size)); - file.seekg(0, std::ios::beg); - file.read(reinterpret_cast(bytes.data()), size); - REQUIRE(file.good()); - return bytes; -} - -void noop_probe_done(const emel::gguf::loader::events::probe_done &) {} -void noop_probe_error(const emel::gguf::loader::events::probe_error &) {} -void noop_bind_done(const emel::gguf::loader::events::bind_done &) {} -void noop_bind_error(const emel::gguf::loader::events::bind_error &) {} -void noop_parse_done(const emel::gguf::loader::events::parse_done &) {} -void noop_parse_error(const emel::gguf::loader::events::parse_error &) {} - void on_mimi_initialized(const mimi::events::initialize_done &done) { g_mimi_frame_samples = done.frame_samples; g_mimi_n_q = done.n_q; @@ -83,20 +49,6 @@ std::vector deterministic_pcm(const int32_t frame_samples) { return pcm; } -struct loaded_moshi_fixture { - std::vector file_bytes = {}; - std::vector kv_arena = {}; - std::vector kv_entries = {}; - std::unique_ptr model = {}; - - emel::model::detail::kv_binding binding() const { - return emel::model::detail::kv_binding{ - .arena = std::span{kv_arena}, - .entries = std::span{kv_entries}, - }; - } -}; - struct recording_graph_executor { int32_t call_count = 0; int32_t external_embedding_count = 0; @@ -352,72 +304,6 @@ bool depformer_kv_probe_bind(void *cache_ptr, const emel::model::data &model, return true; } -void materialize_tensor_names_from_file(emel::model::data &model, - const std::vector &file) { - model.name_bytes_used = 0; - for (uint32_t index = 0; index < model.n_tensors; ++index) { - auto &tensor = model.tensors[index]; - const size_t source_offset = static_cast(tensor.name_offset); - const size_t length = static_cast(tensor.name_length); - REQUIRE(source_offset + length <= file.size()); - REQUIRE(static_cast(model.name_bytes_used) + length <= - model.name_storage.size()); - std::copy_n(file.data() + source_offset, length, - model.name_storage.data() + model.name_bytes_used); - tensor.name_offset = model.name_bytes_used; - model.name_bytes_used += static_cast(length); - } -} - -loaded_moshi_fixture load_fixture_or_skip(const std::string_view name) { - const auto fixture_path = moshi_fixture_path(name); - if (!std::filesystem::exists(fixture_path)) { - MESSAGE("skipping moshi fixture test because fixture is missing: " - << fixture_path.string()); - return {}; - } - - loaded_moshi_fixture loaded{}; - loaded.model = std::make_unique(); - loaded.file_bytes = read_binary_file(fixture_path); - - emel::gguf::loader::sm loader{}; - emel::gguf::loader::requirements requirements{}; - REQUIRE(loader.process_event(emel::gguf::loader::event::probe{ - std::span{loaded.file_bytes}, - requirements, - emel::gguf::loader::event::probe_done_fn::from<&noop_probe_done>(), - emel::gguf::loader::event::probe_error_fn::from<&noop_probe_error>(), - })); - - const uint64_t arena_bytes = - emel::gguf::loader::detail::required_kv_arena_bytes(requirements); - REQUIRE(arena_bytes != UINT64_MAX); - loaded.kv_arena.resize(static_cast(arena_bytes)); - loaded.kv_entries.resize(requirements.kv_count); - loaded.model->n_tensors = requirements.tensor_count; - - REQUIRE(loader.process_event(emel::gguf::loader::event::bind_storage{ - std::span{loaded.kv_arena}, - std::span{loaded.kv_entries}, - std::span{loaded.model->tensors.data(), - loaded.model->n_tensors}, - emel::gguf::loader::event::bind_done_fn::from<&noop_bind_done>(), - emel::gguf::loader::event::bind_error_fn::from<&noop_bind_error>(), - })); - REQUIRE(loader.process_event(emel::gguf::loader::event::parse{ - std::span{loaded.file_bytes}, - emel::gguf::loader::event::parse_done_fn::from<&noop_parse_done>(), - emel::gguf::loader::event::parse_error_fn::from<&noop_parse_error>(), - })); - REQUIRE(emel::model::detail::load_hparams_from_gguf(loaded.binding(), - *loaded.model)); - loaded.model->weights_data = loaded.file_bytes.data(); - loaded.model->weights_size = loaded.file_bytes.size(); - materialize_tensor_names_from_file(*loaded.model, loaded.file_bytes); - return loaded; -} - } // namespace TEST_CASE("speech_moshi_generator_rejects_step_before_initialize") { diff --git a/tests/speech/generator/moshi_personaplex_session_tests.cpp b/tests/speech/generator/moshi_personaplex_session_tests.cpp new file mode 100644 index 00000000..dc2003c5 --- /dev/null +++ b/tests/speech/generator/moshi_personaplex_session_tests.cpp @@ -0,0 +1,497 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "emel/model/data.hpp" +#include "emel/speech/codec/mimi/any.hpp" +#include "emel/speech/generator/moshi/personaplex/session/any.hpp" +#include "moshi_fixture.hpp" + +TEST_CASE("PersonaPlex session runs its injected actors end to end") { + namespace mimi = emel::speech::codec::mimi; + namespace personaplex = emel::speech::generator::moshi::personaplex::session; + namespace sml = stateforward::sml; + using emel::speech::generator::moshi::test::load_fixture_or_skip; + + auto codec = load_fixture_or_skip("mimi-tiny.gguf"); + auto lm = load_fixture_or_skip("moshi-tiny-lm.gguf"); + auto voice = load_fixture_or_skip("moshi-tiny-voice.gguf"); + if (codec.model == nullptr || lm.model == nullptr || voice.model == nullptr) { + return; + } + + std::vector encoder_prepared( + mimi::prepared_arena_floats(*codec.model)); + std::vector encoder_state(mimi::state_arena_floats(*codec.model)); + std::vector encoder_workspace( + mimi::workspace_arena_floats(*codec.model)); + std::vector encoder_frame(mimi::frame_arena_floats(*codec.model)); + std::vector decoder_prepared( + mimi::prepared_arena_floats(*codec.model)); + std::vector decoder_state(mimi::state_arena_floats(*codec.model)); + std::vector decoder_workspace( + mimi::workspace_arena_floats(*codec.model)); + std::vector decoder_frame(mimi::frame_arena_floats(*codec.model)); + + auto &lm_config = lm.model->moshi_lm; + const size_t temporal_per_layer = static_cast(lm_config.context) * + static_cast(lm_config.dim); + std::vector temporal_keys( + static_cast(lm_config.num_layers) * temporal_per_layer, 0u); + std::vector temporal_values(temporal_keys.size(), 0u); + std::vector temporal_offsets( + static_cast(lm_config.num_layers), 0u); + for (int32_t layer = 0; layer < lm_config.num_layers; ++layer) { + temporal_offsets[static_cast(layer)] = + static_cast(layer) * temporal_per_layer; + } + int32_t temporal_offset = 0; + + const size_t depformer_per_layer = + static_cast(lm_config.depformer_context) * + static_cast(lm_config.depformer_dim); + std::vector depformer_keys( + static_cast(lm_config.depformer_num_layers) * depformer_per_layer, + 0u); + std::vector depformer_values(depformer_keys.size(), 0u); + std::vector depformer_offsets( + static_cast(lm_config.depformer_num_layers), 0u); + for (int32_t layer = 0; layer < lm_config.depformer_num_layers; ++layer) { + depformer_offsets[static_cast(layer)] = + static_cast(layer) * depformer_per_layer; + } + int32_t depformer_offset = 0; + + personaplex::dependencies dependencies{ + .temporal_kv = + { + .key_cache = std::span{temporal_keys}, + .value_cache = std::span{temporal_values}, + .layer_cache_offsets = std::span{temporal_offsets}, + .offset = &temporal_offset, + .layer_count = lm_config.num_layers, + .position_capacity = lm_config.context, + .block_tokens = 1, + .kv_dim = lm_config.dim, + }, + .depformer_kv = + { + .key_cache = std::span{depformer_keys}, + .value_cache = std::span{depformer_values}, + .layer_cache_offsets = std::span{depformer_offsets}, + .offset = &depformer_offset, + .layer_count = lm_config.depformer_num_layers, + .position_capacity = lm_config.depformer_context, + .block_tokens = 1, + .kv_dim = lm_config.depformer_dim, + }, + }; + personaplex::sm session{dependencies}; + emel::error::type err = emel::error::cast(personaplex::error::none); + personaplex::event::initialize initialize{ + .mimi_model = *codec.model, + .lm_model = *lm.model, + .voice_model = *voice.model, + .encoder_storage = + { + .prepared = std::span{encoder_prepared}, + .state = std::span{encoder_state}, + .workspace = std::span{encoder_workspace}, + .frame = std::span{encoder_frame}, + }, + .decoder_storage = + { + .prepared = std::span{decoder_prepared}, + .state = std::span{decoder_state}, + .workspace = std::span{decoder_workspace}, + .frame = std::span{decoder_frame}, + }, + .sampling = + { + .enabled = true, + .consume_forced_text = true, + .audio_temperature = 0.8f, + .text_temperature = 0.7f, + .audio_top_k = 250, + .text_top_k = 25, + .seed = 1234, + }, + .max_blocks = 16, + .block_tokens = 4, + .error_out = err, + }; + + auto guard_context = + std::make_unique(dependencies); + personaplex::event::initialize_ctx initialize_ctx{}; + personaplex::event::initialize_run initialize_run{initialize, initialize_ctx}; + const auto request_is_valid = [&] { + return personaplex::guard::guard_initialize_request_valid{}(initialize_run, + *guard_context); + }; + REQUIRE(request_is_valid()); + + const int32_t temporal_layer_count = lm_config.num_layers; + lm_config.num_layers = 0; + CHECK_FALSE(request_is_valid()); + lm_config.num_layers = temporal_layer_count; + const int32_t temporal_context_size = lm_config.context; + lm_config.context = 0; + CHECK_FALSE(request_is_valid()); + lm_config.context = temporal_context_size; + const int32_t temporal_dimension = lm_config.dim; + lm_config.dim = 0; + CHECK_FALSE(request_is_valid()); + lm_config.dim = temporal_dimension; + const int32_t depformer_layer_count = lm_config.depformer_num_layers; + lm_config.depformer_num_layers = 0; + CHECK_FALSE(request_is_valid()); + lm_config.depformer_num_layers = depformer_layer_count; + const int32_t depformer_context_size = lm_config.depformer_context; + lm_config.depformer_context = 0; + CHECK_FALSE(request_is_valid()); + lm_config.depformer_context = depformer_context_size; + const int32_t depformer_dimension = lm_config.depformer_dim; + lm_config.depformer_dim = 0; + CHECK_FALSE(request_is_valid()); + lm_config.depformer_dim = depformer_dimension; + const int32_t inference_dep_q = lm_config.inference_dep_q; + lm_config.inference_dep_q = 0; + CHECK_FALSE(request_is_valid()); + lm_config.inference_dep_q = inference_dep_q; + const int32_t codec_n_q = codec.model->mimi.n_q; + codec.model->mimi.n_q = 0; + CHECK_FALSE(request_is_valid()); + codec.model->mimi.n_q = codec_n_q; + const int32_t lm_card = lm_config.card; + lm_config.card = 0; + CHECK_FALSE(request_is_valid()); + lm_config.card = lm_card; + const int32_t codec_card = codec.model->mimi.card; + codec.model->mimi.card = 0; + CHECK_FALSE(request_is_valid()); + codec.model->mimi.card = codec_card; + + initialize.sampling.enabled = false; + CHECK_FALSE(request_is_valid()); + initialize.sampling.enabled = true; + initialize.sampling.consume_forced_text = false; + CHECK_FALSE(request_is_valid()); + initialize.sampling.consume_forced_text = true; + initialize.sampling.audio_temperature = 0.0f; + CHECK_FALSE(request_is_valid()); + initialize.sampling.audio_temperature = 0.8f; + initialize.sampling.text_temperature = 0.0f; + CHECK_FALSE(request_is_valid()); + initialize.sampling.text_temperature = 0.7f; + initialize.sampling.audio_top_k = 0; + CHECK_FALSE(request_is_valid()); + initialize.sampling.audio_top_k = 250; + initialize.sampling.text_top_k = 0; + CHECK_FALSE(request_is_valid()); + initialize.sampling.text_top_k = 25; + initialize.sampling.seed = 0; + CHECK_FALSE(request_is_valid()); + initialize.sampling.seed = 1234; + initialize.max_blocks = 0; + CHECK_FALSE(request_is_valid()); + initialize.max_blocks = 16; + initialize.block_tokens = 0; + CHECK_FALSE(request_is_valid()); + initialize.block_tokens = 4; + + lm_config.inference_dep_q = inference_dep_q + 1; + CHECK_FALSE(request_is_valid()); + lm_config.inference_dep_q = inference_dep_q; + lm_config.card = lm_card + 1; + CHECK_FALSE(request_is_valid()); + lm_config.card = lm_card; + + const auto temporal_key_view = guard_context->temporal_kv.key_cache; + guard_context->temporal_kv.key_cache = {}; + CHECK_FALSE(request_is_valid()); + guard_context->temporal_kv.key_cache = temporal_key_view; + const auto temporal_value_view = guard_context->temporal_kv.value_cache; + guard_context->temporal_kv.value_cache = {}; + CHECK_FALSE(request_is_valid()); + guard_context->temporal_kv.value_cache = temporal_value_view; + int32_t *const temporal_offset_ptr = guard_context->temporal_kv.offset; + guard_context->temporal_kv.offset = nullptr; + CHECK_FALSE(request_is_valid()); + guard_context->temporal_kv.offset = temporal_offset_ptr; + const auto temporal_layer_views = + guard_context->temporal_kv.layer_cache_offsets; + guard_context->temporal_kv.layer_cache_offsets = {}; + CHECK_FALSE(request_is_valid()); + guard_context->temporal_kv.layer_cache_offsets = temporal_layer_views; + --guard_context->temporal_kv.layer_count; + CHECK_FALSE(request_is_valid()); + ++guard_context->temporal_kv.layer_count; + --guard_context->temporal_kv.position_capacity; + CHECK_FALSE(request_is_valid()); + ++guard_context->temporal_kv.position_capacity; + guard_context->temporal_kv.block_tokens = 0; + CHECK_FALSE(request_is_valid()); + guard_context->temporal_kv.block_tokens = 1; + --guard_context->temporal_kv.kv_dim; + CHECK_FALSE(request_is_valid()); + ++guard_context->temporal_kv.kv_dim; + + const auto depformer_key_view = guard_context->depformer_kv.key_cache; + guard_context->depformer_kv.key_cache = {}; + CHECK_FALSE(request_is_valid()); + guard_context->depformer_kv.key_cache = depformer_key_view; + const auto depformer_value_view = guard_context->depformer_kv.value_cache; + guard_context->depformer_kv.value_cache = {}; + CHECK_FALSE(request_is_valid()); + guard_context->depformer_kv.value_cache = depformer_value_view; + int32_t *const depformer_offset_ptr = guard_context->depformer_kv.offset; + guard_context->depformer_kv.offset = nullptr; + CHECK_FALSE(request_is_valid()); + guard_context->depformer_kv.offset = depformer_offset_ptr; + const auto depformer_layer_views = + guard_context->depformer_kv.layer_cache_offsets; + guard_context->depformer_kv.layer_cache_offsets = {}; + CHECK_FALSE(request_is_valid()); + guard_context->depformer_kv.layer_cache_offsets = depformer_layer_views; + --guard_context->depformer_kv.layer_count; + CHECK_FALSE(request_is_valid()); + ++guard_context->depformer_kv.layer_count; + --guard_context->depformer_kv.position_capacity; + CHECK_FALSE(request_is_valid()); + ++guard_context->depformer_kv.position_capacity; + guard_context->depformer_kv.block_tokens = 0; + CHECK_FALSE(request_is_valid()); + guard_context->depformer_kv.block_tokens = 1; + --guard_context->depformer_kv.kv_dim; + CHECK_FALSE(request_is_valid()); + ++guard_context->depformer_kv.kv_dim; + guard_context.reset(); + + REQUIRE(session.process_event(initialize)); + + for (int32_t step = 0; + step < 16 && session.is(sml::state); + ++step) { + personaplex::event::advance_voice advance{.error_out = err}; + REQUIRE(session.process_event(advance)); + } + for (int32_t step = 0; + step < 16 && session.is(sml::state); + ++step) { + personaplex::event::advance_prompt advance{ + .text_token = -1, + .error_out = err, + }; + REQUIRE(session.process_event(advance)); + } + REQUIRE(session.is(sml::state)); + + const int32_t frame_samples = static_cast( + std::lround(static_cast(codec.model->mimi.sample_rate) / + static_cast(codec.model->mimi.frame_rate))); + const int32_t public_n_q = lm_config.inference_dep_q; + std::vector pcm(static_cast(frame_samples), 0.0f); + for (int32_t index = 0; index < frame_samples; ++index) { + pcm[static_cast(index)] = + 0.04f * static_cast((index % 97) - 48) / 48.0f; + } + std::vector input_codes(static_cast(public_n_q), -1); + std::vector output_codes(static_cast(public_n_q), -1); + std::vector output_pcm(static_cast(frame_samples), 0.0f); + int32_t text_token = -1; + bool produced = false; + personaplex::event::live_frame live{ + .payload = + { + .pcm = std::span{pcm}, + .input_codes_out = std::span{input_codes}, + .output_codes_out = std::span{output_codes}, + .text_token_out = text_token, + .produced_out = produced, + .pcm_out = std::span{output_pcm}, + }, + .error_out = err, + }; + REQUIRE(session.process_event(live)); + + personaplex::event::begin_flush begin_flush{.error_out = err}; + REQUIRE(session.process_event(begin_flush)); + std::fill(pcm.begin(), pcm.end(), 0.0f); + for (int32_t step = 0; step < 8 && !produced; ++step) { + personaplex::event::flush_frame flush{ + .payload = + { + .pcm = std::span{pcm}, + .input_codes_out = std::span{input_codes}, + .output_codes_out = std::span{output_codes}, + .text_token_out = text_token, + .produced_out = produced, + .pcm_out = std::span{output_pcm}, + }, + .error_out = err, + }; + REQUIRE(session.process_event(flush)); + } + REQUIRE(produced); + CHECK(std::any_of(output_pcm.begin(), output_pcm.end(), + [](const float sample) { return sample != 0.0f; })); + + personaplex::event::finish finish{.error_out = err}; + REQUIRE(session.process_event(finish)); + CHECK(session.is(sml::state)); +} + +TEST_CASE("PersonaPlex session rejects invalid injected dependencies") { + namespace personaplex = emel::speech::generator::moshi::personaplex::session; + namespace sml = stateforward::sml; + + auto model = std::make_unique(); + personaplex::dependencies dependencies{}; + personaplex::sm session{dependencies}; + emel::error::type err = emel::error::cast(personaplex::error::none); + personaplex::event::initialize initialize{ + .mimi_model = *model, + .lm_model = *model, + .voice_model = *model, + .sampling = + { + .enabled = true, + .consume_forced_text = true, + .audio_temperature = 0.8f, + .text_temperature = 0.7f, + .audio_top_k = 250, + .text_top_k = 25, + .seed = 1234, + }, + .max_blocks = 4, + .block_tokens = 4, + .error_out = err, + }; + + CHECK_FALSE(session.process_event(initialize)); + CHECK(err == emel::error::cast(personaplex::error::invalid_request)); + CHECK(session.is(sml::state)); +} + +TEST_CASE("PersonaPlex session models unexpected event ordering") { + namespace personaplex = emel::speech::generator::moshi::personaplex::session; + namespace sml = stateforward::sml; + + personaplex::dependencies dependencies{}; + personaplex::sm session{dependencies}; + emel::error::type err = emel::error::cast(personaplex::error::none); + personaplex::event::finish finish{.error_out = err}; + + CHECK_FALSE(session.process_event(finish)); + CHECK(err == emel::error::cast(personaplex::error::unexpected_event)); + CHECK(session.is(sml::state)); +} + +TEST_CASE("PersonaPlex session guards and effects expose failure routes") { + namespace personaplex = emel::speech::generator::moshi::personaplex::session; + + auto model = std::make_unique(); + personaplex::dependencies dependencies{}; + auto context = std::make_unique(dependencies); + emel::error::type err = emel::error::cast(personaplex::error::none); + personaplex::event::initialize initialize{ + .mimi_model = *model, + .lm_model = *model, + .voice_model = *model, + .error_out = err, + }; + personaplex::event::initialize_ctx initialize_ctx{}; + personaplex::event::initialize_run initialize_run{initialize, initialize_ctx}; + + CHECK(personaplex::guard::guard_encoder_initialize_failed{}(initialize_run, + *context)); + initialize_ctx.child_accepted = true; + initialize_ctx.frame_samples = 1920; + initialize_ctx.mimi_n_q = 8; + model->moshi_lm.inference_dep_q = 8; + CHECK(personaplex::guard::guard_encoder_initialize_succeeded{}(initialize_run, + *context)); + CHECK(personaplex::guard::guard_child_succeeded< + personaplex::event::initialize_run>{}(initialize_run, *context)); + CHECK_FALSE(personaplex::guard::guard_child_failed< + personaplex::event::initialize_run>{}(initialize_run, *context)); + personaplex::action::effect_fail_initialize_child< + personaplex::error::codec_initialize_failed>{}(initialize_run, *context); + CHECK(err == emel::error::cast(personaplex::error::codec_initialize_failed)); + + personaplex::event::advance_voice voice{.error_out = err}; + personaplex::event::phase_ctx voice_ctx{}; + personaplex::event::advance_voice_run voice_run{voice, voice_ctx}; + voice_ctx.child_accepted = true; + CHECK(personaplex::guard::guard_phase_succeeded_incomplete< + personaplex::event::advance_voice_run>{}(voice_run, *context)); + voice_ctx.complete = true; + CHECK(personaplex::guard::guard_phase_succeeded_complete< + personaplex::event::advance_voice_run>{}(voice_run, *context)); + voice_ctx.graph_err = 1; + CHECK(personaplex::guard::guard_phase_failed< + personaplex::event::advance_voice_run>{}(voice_run, *context)); + personaplex::action::effect_fail_advance_voice< + personaplex::error::voice_prefill_failed>{}(voice_run, *context); + CHECK(err == emel::error::cast(personaplex::error::voice_prefill_failed)); + + personaplex::event::advance_prompt prompt{ + .text_token = -1, + .error_out = err, + }; + personaplex::event::phase_ctx prompt_ctx{}; + personaplex::event::advance_prompt_run prompt_run{prompt, prompt_ctx}; + personaplex::action::effect_fail_advance_prompt< + personaplex::error::prompt_prefill_failed>{}(prompt_run, *context); + CHECK(err == emel::error::cast(personaplex::error::prompt_prefill_failed)); + + int32_t text_token = -1; + bool produced = true; + personaplex::event::live_frame live{ + .payload = + { + .text_token_out = text_token, + .produced_out = produced, + }, + .error_out = err, + }; + personaplex::event::frame_ctx frame_ctx{}; + personaplex::event::live_frame_run live_run{live, frame_ctx}; + CHECK(personaplex::guard::guard_frame_request_invalid< + personaplex::event::live_frame_run>{}(live_run, *context)); + frame_ctx.child_accepted = true; + frame_ctx.produced = true; + CHECK(personaplex::guard::guard_frame_generated_and_produced< + personaplex::event::live_frame_run>{}(live_run, *context)); + frame_ctx.produced = false; + CHECK(personaplex::guard::guard_frame_generated_without_output< + personaplex::event::live_frame_run>{}(live_run, *context)); + frame_ctx.child_err = 1; + CHECK(personaplex::guard::guard_frame_generate_failed< + personaplex::event::live_frame_run>{}(live_run, *context)); + personaplex::action::effect_fail_frame{}( + live_run, *context); + CHECK_FALSE(produced); + CHECK(err == emel::error::cast(personaplex::error::generate_failed)); + + personaplex::event::begin_flush begin_flush{.error_out = err}; + personaplex::event::simple_ctx begin_flush_ctx{}; + personaplex::event::begin_flush_run begin_flush_run{begin_flush, + begin_flush_ctx}; + personaplex::action::effect_fail_begin_flush_invalid{}(begin_flush_run, + *context); + CHECK(err == emel::error::cast(personaplex::error::invalid_request)); + + personaplex::event::finish finish{.error_out = err}; + personaplex::event::simple_ctx finish_ctx{}; + personaplex::event::finish_run finish_run{finish, finish_ctx}; + personaplex::action::effect_fail_finish_invalid{}(finish_run, *context); + CHECK(err == emel::error::cast(personaplex::error::invalid_request)); +} diff --git a/tools/bench/CMakeLists.txt b/tools/bench/CMakeLists.txt index 494b2513..4266ca9b 100644 --- a/tools/bench/CMakeLists.txt +++ b/tools/bench/CMakeLists.txt @@ -33,7 +33,8 @@ if(EMEL_BENCH_SUITE_FILTER STREQUAL "batch_planner" OR # subtree, which the moshi reference driver links against; an MLX-only # compare (EMEL_BENCH_SKIP_MOSHI_REFERENCE) builds no such driver. (EMEL_BENCH_SUITE_FILTER STREQUAL "speech_codec_mimi" AND - NOT EMEL_BENCH_SKIP_MOSHI_REFERENCE)) + NOT EMEL_BENCH_SKIP_MOSHI_REFERENCE) OR + EMEL_BENCH_SUITE_FILTER STREQUAL "speech_dialogue_moshi") set(EMEL_BENCH_NEEDS_LLAMA ON) endif() @@ -283,6 +284,9 @@ if(EMEL_BENCH_NEEDS_LLAMA) set(GGML_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GGML_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + if(EMEL_BENCH_SUITE_FILTER STREQUAL "speech_dialogue_moshi") + set(GGML_METAL OFF CACHE BOOL "CPU-only PersonaPlex reference lane" FORCE) + endif() set(LLAMA_BUILD_NUMBER 0 CACHE STRING "" FORCE) set(LLAMA_INSTALL_VERSION 0.0.0 CACHE STRING "" FORCE) add_subdirectory(${reference_impl_SOURCE_DIR}/ggml ggml) @@ -455,6 +459,7 @@ add_bench_runner_suite(tokenizer text/tokenizer/tokenizer_bench.cpp EMEL_BENCH_E if(NOT EMEL_BENCH_SUITE_FILTER STREQUAL "" AND NOT EMEL_BENCH_SUITE_FILTER STREQUAL "whisper_compare" AND + NOT EMEL_BENCH_SUITE_FILTER STREQUAL "speech_dialogue_moshi" AND BENCH_RUNNER_COMPILE_DEFINITIONS STREQUAL "") message(FATAL_ERROR "Unknown EMEL_BENCH_SUITE_FILTER='${EMEL_BENCH_SUITE_FILTER}'") endif() @@ -480,6 +485,10 @@ add_executable(mimi_emel_parity_runner ${CMAKE_CURRENT_SOURCE_DIR}/speech/mimi_emel_parity_runner.cpp ) +add_executable(personaplex_emel_runner + ${CMAKE_CURRENT_SOURCE_DIR}/speech/personaplex_emel_runner.cpp +) + target_link_libraries(mimi_emel_parity_runner PRIVATE emel_core @@ -494,6 +503,20 @@ target_include_directories(mimi_emel_parity_runner ${EMEL_ROOT}/include ) +target_link_libraries(personaplex_emel_runner + PRIVATE + emel_core + emel +) + +target_include_directories(personaplex_emel_runner + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${EMEL_ROOT} + ${EMEL_ROOT}/src + ${EMEL_ROOT}/include +) + # Reference-lane Mimi driver: moshi.cpp lib sources + ggml + SentencePiece. # Never linked into bench_runner or the EMEL lane; invoked as a subprocess # via reference_backends/moshi_cpp_mimi.json (two-lane isolation). @@ -641,6 +664,26 @@ add_test( COMMAND diarization_compare_tests ) +add_executable(personaplex_compare_tests + ${CMAKE_CURRENT_SOURCE_DIR}/personaplex_compare_tests.cpp +) + +target_include_directories(personaplex_compare_tests + PRIVATE + ${DOCTEST_INCLUDE_DIR} +) + +target_compile_definitions(personaplex_compare_tests + PRIVATE + BENCH_REPO_ROOT="${EMEL_ROOT}" + PERSONAPLEX_COMPARE_SCRIPT_PATH="${CMAKE_CURRENT_SOURCE_DIR}/personaplex_compare.py" +) + +add_test( + NAME personaplex_compare_tests + COMMAND personaplex_compare_tests +) + add_executable(whisper_benchmark_tests ${CMAKE_CURRENT_SOURCE_DIR}/whisper_benchmark_tests.cpp ) diff --git a/tools/bench/bench_dependency_manifest.cpp b/tools/bench/bench_dependency_manifest.cpp index 0bcf6232..216d2042 100644 --- a/tools/bench/bench_dependency_manifest.cpp +++ b/tools/bench/bench_dependency_manifest.cpp @@ -380,6 +380,10 @@ constexpr std::array k_records{ kind::script, "tools/bench/moshi_gguf_convert.py", "emel_lane_converter"}, + dependency_record{"speech_codec_mimi", + kind::config, + "tools/bench/personaplex-inference.json", + "inference_contract"}, dependency_record{"speech_codec_mimi", kind::config, "tools/bench/moshi_reference_ref.txt", @@ -412,6 +416,10 @@ constexpr std::array k_records{ kind::script, "tools/bench/moshi_gguf_convert.py", "emel_lane_converter"}, + dependency_record{"speech_lm_moshi", + kind::config, + "tools/bench/personaplex-inference.json", + "inference_contract"}, // MLX-only inputs map to the MLX suite: quality_gates.sh runs the // personaplex-mlx compare lane only for speech_codec_mimi_mlx, so routing // these through the generic mimi suite would gate MLX regressions with diff --git a/tools/bench/dependency_manifest.txt b/tools/bench/dependency_manifest.txt index cd61e9cc..7a4e8ff6 100644 --- a/tools/bench/dependency_manifest.txt +++ b/tools/bench/dependency_manifest.txt @@ -102,6 +102,7 @@ record runner=speech_codec_mimi kind=fixture path=tests/models/mimi-tiny.gguf re record runner=speech_codec_mimi kind=script path=tools/bench/mimi_compare.py reason=operator_compare record runner=speech_codec_mimi kind=script path=scripts/bench_mimi_compare.sh reason=compare_wrapper record runner=speech_codec_mimi kind=script path=tools/bench/moshi_gguf_convert.py reason=emel_lane_converter +record runner=speech_codec_mimi kind=config path=tools/bench/personaplex-inference.json reason=inference_contract record runner=speech_codec_mimi kind=config path=tools/bench/moshi_reference_ref.txt reason=reference_pin record runner=speech_codec_mimi kind=config path=tools/bench/reference_backends/moshi_cpp_mimi.json reason=reference_backend_descriptor record runner=speech_codec_mimi kind=script path=scripts/setup_moshi_cpp_reference.sh reason=reference_setup @@ -110,6 +111,7 @@ record runner=speech_lm_moshi kind=source path=src/emel/model/moshi reason=model record runner=speech_lm_moshi kind=script path=scripts/bench_moshi_lm_compare.sh reason=compare_wrapper record runner=speech_lm_moshi kind=script path=scripts/setup_moshi_cpp_reference.sh reason=reference_setup record runner=speech_lm_moshi kind=script path=tools/bench/moshi_gguf_convert.py reason=emel_lane_converter +record runner=speech_lm_moshi kind=config path=tools/bench/personaplex-inference.json reason=inference_contract record runner=speech_codec_mimi_mlx kind=script path=tools/bench/mimi_compare.py reason=operator_compare record runner=speech_codec_mimi_mlx kind=script path=scripts/bench_mimi_compare.sh reason=compare_wrapper record runner=speech_codec_mimi_mlx kind=script path=scripts/setup_personaplex_mlx_reference.sh reason=reference_setup diff --git a/tools/bench/moshi_gguf_convert.py b/tools/bench/moshi_gguf_convert.py index 0bac1ee3..42640da0 100644 --- a/tools/bench/moshi_gguf_convert.py +++ b/tools/bench/moshi_gguf_convert.py @@ -334,8 +334,22 @@ def require_elements(infos: list[TensorInfo], name: str, f"elements), the runtime bind consumes {elements}") -def load_lm_config(path: Path) -> dict: +def inject_inference_config(config: dict, + inference_config_path: Path | None) -> None: + if inference_config_path is None: + return + inference = json.loads( + inference_config_path.read_text(encoding="utf-8")) + if not isinstance(inference, dict): + raise ValueError( + f"{inference_config_path}: inference config must be an object") + config["inference"] = inference + + +def load_lm_config(path: Path, + inference_config_path: Path | None = None) -> dict: config = json.loads(path.read_text(encoding="utf-8")) + inject_inference_config(config, inference_config_path) required = [ "card", "n_q", "dep_q", "text_card", "existing_text_padding_id", "dim", "num_heads", "num_layers", "hidden_scale", "causal", "context", @@ -512,10 +526,12 @@ def get_value(key: str): config["inference_post_text_silence_frames"] = post_silence -def resolve_mimi_n_q(config_path: Path | None) -> int: +def resolve_mimi_n_q(config_path: Path | None, + inference_config_path: Path | None = None) -> int: if config_path is None: - return 16 + raise ValueError("Mimi conversion requires --config or --mimi-n-q") config = json.loads(config_path.read_text(encoding="utf-8")) + inject_inference_config(config, inference_config_path) if "n_q" not in config: raise ValueError(f"{config_path}: mimi conversion config requires n_q") if not isinstance(config["n_q"], int): @@ -1517,13 +1533,19 @@ def convert(source: Path, output: Path, config_path: Path | None, tokenizer_path: Path | None, mimi_preset_path: Path | None = None, quantize: str | None = None, - pack_lm_q4_k: str | None = None) -> dict: + pack_lm_q4_k: str | None = None, + inference_config_path: Path | None = None, + mimi_n_q: int | None = None) -> dict: infos, data_start = read_raw_gguf(source) component = detect_component(infos) if quantize is not None and component != "mimi": raise ValueError("--quantize currently supports mimi components only") if pack_lm_q4_k is not None and component != "lm": raise ValueError("--pack-lm-q4-k supports lm components only") + if mimi_n_q is not None and component != "mimi": + raise ValueError("--mimi-n-q supports Mimi components only") + if mimi_n_q is not None and mimi_n_q <= 0: + raise ValueError("--mimi-n-q must be a positive integer") if quantize is not None and pack_lm_q4_k is not None: raise ValueError("--quantize and --pack-lm-q4-k are component-specific") @@ -1537,7 +1559,7 @@ def convert(source: Path, output: Path, config_path: Path | None, raise ValueError("--config is required for lm components") if tokenizer_path is None: raise ValueError("--tokenizer is required for lm components") - config = load_lm_config(config_path) + config = load_lm_config(config_path, inference_config_path) num_weights = depformer_weight_count(config) candidates = transformer_layer_candidates( "lm.transformer.", config["num_layers"], 1) @@ -1553,7 +1575,8 @@ def convert(source: Path, output: Path, config_path: Path | None, preset = dict(MIMI_PRESET) if mimi_preset_path is not None: preset.update(json.loads(mimi_preset_path.read_text(encoding="utf-8"))) - n_q = resolve_mimi_n_q(config_path) + n_q = (mimi_n_q if mimi_n_q is not None else + resolve_mimi_n_q(config_path, inference_config_path)) layers = preset["transformer_num_layers"] candidates = transformer_layer_candidates( "mimi.encoder_transformer.transformer.", layers, 1) @@ -1595,6 +1618,11 @@ def convert(source: Path, output: Path, config_path: Path | None, if pack_lm_q4_k is not None: manifest["lm_tensor_packing"] = pack_lm_q4_k manifest["packed_tensors"] = packed_count + if inference_config_path is not None: + manifest["inference_config"] = str(inference_config_path) + manifest["inference_config_sha256"] = sha256_file(inference_config_path) + if mimi_n_q is not None: + manifest["mimi_n_q"] = mimi_n_q return manifest @@ -1606,8 +1634,14 @@ def parse_args() -> argparse.Namespace: help="enriched emel moshi GGUF to write") parser.add_argument("--config", type=Path, default=None, help="moshi config JSON (personaplex-config.json); " - "required for lm components; optional for mimi " - "components to declare active inference n_q") + "required for lm components and for mimi unless " + "--mimi-n-q is injected") + parser.add_argument("--inference-config", type=Path, default=None, + help="injected inference-only JSON overlay for prompt " + "tokens, public codebooks, and silence framing") + parser.add_argument("--mimi-n-q", type=int, default=None, + help="explicit injected Mimi codebook count; used to " + "keep full-codec and PersonaPlex artifacts separate") parser.add_argument("--tokenizer", type=Path, default=None, help="SentencePiece .model file; required for lm " "components") @@ -1630,7 +1664,8 @@ def parse_args() -> argparse.Namespace: def main() -> int: args = parse_args() manifest = convert(args.source, args.output, args.config, args.tokenizer, - args.mimi_preset, args.quantize, args.pack_lm_q4_k) + args.mimi_preset, args.quantize, args.pack_lm_q4_k, + args.inference_config, args.mimi_n_q) if args.manifest is not None: args.manifest.parent.mkdir(parents=True, exist_ok=True) args.manifest.write_text(json.dumps(manifest, indent=2) + "\n", diff --git a/tools/bench/personaplex-inference.json b/tools/bench/personaplex-inference.json new file mode 100644 index 00000000..0f66b62b --- /dev/null +++ b/tools/bench/personaplex-inference.json @@ -0,0 +1,28 @@ +{ + "dep_q": 8, + "prompt_tokens": [ + 3, + 948, + 243, + 1178, + 546, + 1736, + 1030, + 1978, + 2008, + 430, + 1268, + 381, + 1611, + 1095, + 1495, + 56, + 472 + ], + "pre_text_silence_frames": 6, + "post_text_silence_frames": 6, + "max_blocks": 256, + "block_tokens": 4, + "prompt_text_token": -1, + "frame_samples": 1920 +} diff --git a/tools/bench/personaplex_compare.py b/tools/bench/personaplex_compare.py new file mode 100755 index 00000000..a24c5e29 --- /dev/null +++ b/tools/bench/personaplex_compare.py @@ -0,0 +1,368 @@ +#!/usr/bin/env python3 +"""CPU-only fixed-seed PersonaPlex E2E comparison (personaplex_compare/v1).""" + +import argparse +import hashlib +import json +import math +import re +import struct +import subprocess +import sys +import time +import wave +from pathlib import Path + + +def run_lane(command: list[str], stdout_path: Path, stderr_path: Path) -> float: + started = time.monotonic() + with stdout_path.open("w") as stdout, stderr_path.open("w") as stderr: + result = subprocess.run(command, stdout=stdout, stderr=stderr, check=False) + elapsed = time.monotonic() - started + if result.returncode != 0: + raise RuntimeError( + f"lane failed with status {result.returncode}: {' '.join(command)}\n" + f"stderr: {stderr_path}") + return elapsed + + +def parse_codes(line: str) -> list[int]: + return [int(value) for value in line.split("codes=", 1)[1].strip().split(",")] + + +def parse_emel_log(path: Path) -> tuple[list[list[int]], list[list[int]], list[int]]: + input_frames = [] + output_frames = [] + text_tokens = [] + pattern = re.compile(r"text=(-?\d+).*codes=([0-9,-]+)") + for line in path.read_text().splitlines(): + if line.startswith("EMEL_INPUT "): + input_frames.append(parse_codes(line)) + elif line.startswith("EMEL_OUTPUT "): + match = pattern.search(line) + if match is None: + raise ValueError(f"malformed EMEL graph line: {line}") + text_tokens.append(int(match.group(1))) + output_frames.append([int(value) for value in match.group(2).split(",")]) + return input_frames, output_frames, text_tokens + + +def parse_reference_log(path: Path) -> tuple[list[list[int]], list[list[int]], list[int]]: + input_frames = [] + output_frames = [] + text_tokens = [] + pattern = re.compile(r"text=(-?\d+).*codes=([0-9,-]+)") + for line in path.read_text().splitlines(): + if line.startswith("input "): + input_frames.append(parse_codes(line)) + elif line.startswith("output "): + match = pattern.search(line) + if match is None: + raise ValueError(f"malformed reference output line: {line}") + text_tokens.append(int(match.group(1))) + output_frames.append([int(value) for value in match.group(2).split(",")]) + return input_frames, output_frames, text_tokens + + +def match_fraction(left: list[list[int]], right: list[list[int]], streams: int) -> float: + if len(left) != len(right) or not left: + return 0.0 + matched = 0 + total = 0 + for left_frame, right_frame in zip(left, right): + width = min(streams, len(left_frame), len(right_frame)) + matched += sum(a == b for a, b in zip(left_frame[:width], right_frame[:width])) + total += width + return matched / total if total else 0.0 + + +def common_token_prefix(left: list[list[int]], right: list[list[int]]) -> int: + count = 0 + for left_frame, right_frame in zip(left, right): + for left_token, right_token in zip(left_frame, right_frame): + if left_token != right_token: + return count + count += 1 + if len(left_frame) != len(right_frame): + return count + return count + + +def read_wav(path: Path) -> tuple[int, list[float]]: + with wave.open(str(path), "rb") as source: + if (source.getnchannels(), source.getsampwidth()) != (1, 2): + raise ValueError(f"expected mono s16 WAV: {path}") + sample_rate = source.getframerate() + raw = source.readframes(source.getnframes()) + samples = struct.unpack(f"<{len(raw) // 2}h", raw) + return sample_rate, [sample / 32768.0 for sample in samples] + + +def audio_metrics(samples: list[float], sample_rate: int) -> dict[str, object]: + energy = sum(sample * sample for sample in samples) + rms = math.sqrt(energy / len(samples)) if samples else 0.0 + peak = max((abs(sample) for sample in samples), default=0.0) + window = max(1, int(sample_rate * 0.08)) + frame_rms = [] + for begin in range(0, len(samples), window): + frame = samples[begin:begin + window] + frame_energy = sum(sample * sample for sample in frame) + frame_rms.append(math.sqrt(frame_energy / len(frame))) + active = sum(value >= 0.01 for value in frame_rms) + return { + "samples": len(samples), + "seconds": len(samples) / sample_rate, + "peak": peak, + "rms": rms, + "active_ratio": active / len(frame_rms) if frame_rms else 0.0, + "frame_rms": frame_rms, + } + + +def correlation(left: list[float], right: list[float]) -> float: + if len(left) != len(right) or len(left) < 2: + return 0.0 + left_mean = sum(left) / len(left) + right_mean = sum(right) / len(right) + numerator = sum((a - left_mean) * (b - right_mean) + for a, b in zip(left, right)) + left_energy = sum((value - left_mean) ** 2 for value in left) + right_energy = sum((value - right_mean) ** 2 for value in right) + denominator = math.sqrt(left_energy * right_energy) + return numerator / denominator if denominator else 0.0 + + +def best_energy_correlation(left: list[float], right: list[float], max_lag: int) -> tuple[float, int]: + best = (-2.0, 0) + for lag in range(-max_lag, max_lag + 1): + if lag < 0: + current = correlation(left[-lag:], right[:len(right) + lag]) + elif lag > 0: + current = correlation(left[:len(left) - lag], right[lag:]) + else: + current = correlation(left, right) + if current > best[0]: + best = (current, lag) + return best + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as source: + while block := source.read(1024 * 1024): + digest.update(block) + return digest.hexdigest() + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--emel-runner", required=True) + parser.add_argument("--reference-driver", required=True) + parser.add_argument("--emel-mimi", required=True) + parser.add_argument("--reference-mimi", required=True) + parser.add_argument("--emel-lm", required=True) + parser.add_argument("--reference-lm", required=True) + parser.add_argument("--emel-voice", required=True) + parser.add_argument("--reference-voice", required=True) + parser.add_argument("--config", required=True) + parser.add_argument("--inference-config", required=True) + parser.add_argument("--audio", required=True) + parser.add_argument("--output-dir", required=True) + parser.add_argument("--frames", type=int, default=125) + parser.add_argument("--seed", type=int, default=1234) + parser.add_argument("--threads", type=int, default=1) + parser.add_argument("--audio-temperature", type=float, default=0.8) + parser.add_argument("--text-temperature", type=float, default=0.7) + parser.add_argument("--audio-top-k", type=int, default=250) + parser.add_argument("--text-top-k", type=int, default=25) + parser.add_argument("--min-output-match", type=float, default=0.15) + parser.add_argument("--min-first-four-match", type=float, default=0.30) + parser.add_argument("--min-energy-correlation", type=float, default=0.30) + parser.add_argument("--max-active-ratio-delta", type=float, default=0.35) + args = parser.parse_args() + if args.frames <= 0 or args.seed <= 0 or args.threads <= 0: + parser.error("frames, seed, and threads must be positive") + + inference_path = Path(args.inference_config) + inference = json.loads(inference_path.read_text(encoding="utf-8")) + required_inference = ( + "dep_q", "max_blocks", "block_tokens", "prompt_text_token", + "frame_samples") + if any(not isinstance(inference.get(key), int) + for key in required_inference): + parser.error("inference config integer contract is incomplete") + public_n_q = inference["dep_q"] + max_blocks = inference["max_blocks"] + block_tokens = inference["block_tokens"] + prompt_text_token = inference["prompt_text_token"] + frame_samples = inference["frame_samples"] + if (public_n_q <= 0 or max_blocks <= 0 or block_tokens <= 0 or + frame_samples <= 0): + parser.error( + "inference dep_q, max_blocks, block_tokens, and frame_samples must " + "be positive") + + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + emel_wav = output_dir / "emel_personaplex.wav" + reference_wav = output_dir / "moshi_cpp_personaplex.wav" + emel_stdout = output_dir / "emel.stdout.log" + emel_stderr = output_dir / "emel.stderr.log" + reference_stdout = output_dir / "moshi_cpp.stdout.log" + reference_stderr = output_dir / "moshi_cpp.stderr.log" + + emel_elapsed = run_lane([ + args.emel_runner, + args.emel_mimi, + args.emel_lm, + args.emel_voice, + args.audio, + str(emel_wav), + str(args.frames), + str(args.seed), + str(args.audio_temperature), + str(args.text_temperature), + str(args.audio_top_k), + str(args.text_top_k), + str(max_blocks), + str(block_tokens), + str(prompt_text_token), + ], emel_stdout, emel_stderr) + reference_elapsed = run_lane([ + args.reference_driver, + "personaplex", + "--config", args.config, + "--lm", args.reference_lm, + "--mimi", args.reference_mimi, + "--voice", args.reference_voice, + "--audio", args.audio, + "--out", str(reference_wav), + "--frames", str(args.frames), + "--threads", str(args.threads), + "--seed", str(args.seed), + "--n-q", str(public_n_q), + "--audio-temperature", str(args.audio_temperature), + "--text-temperature", str(args.text_temperature), + ], reference_stdout, reference_stderr) + + emel_input, emel_output, emel_text = parse_emel_log(emel_stderr) + ref_input, ref_output, ref_text = parse_reference_log(reference_stdout) + input_rate, input_samples = read_wav(Path(args.audio)) + if input_rate != 24000: + raise RuntimeError("input WAV sample rate must be 24 kHz") + audio_input_frames = ( + len(input_samples) + frame_samples - 1) // frame_samples + emel_wav_input = emel_input[:audio_input_frames] + ref_public_input = [frame[:public_n_q] + for frame in ref_input[:audio_input_frames]] + input_match = match_fraction( + emel_wav_input, ref_public_input, public_n_q) + output_match = match_fraction(emel_output, ref_output, public_n_q) + first_four_match = match_fraction( + emel_output, ref_output, min(4, public_n_q)) + text_match = (sum(a == b for a, b in zip(emel_text, ref_text)) / + len(emel_text) if len(emel_text) == len(ref_text) and emel_text + else 0.0) + + emel_rate, emel_samples = read_wav(emel_wav) + reference_rate, reference_samples = read_wav(reference_wav) + if emel_rate != reference_rate: + raise RuntimeError("output WAV sample-rate mismatch") + emel_audio = audio_metrics(emel_samples, emel_rate) + reference_audio = audio_metrics(reference_samples, reference_rate) + emel_log_energy = [math.log(max(value, 1.0e-8)) + for value in emel_audio.pop("frame_rms")] + reference_log_energy = [math.log(max(value, 1.0e-8)) + for value in reference_audio.pop("frame_rms")] + energy_correlation, energy_lag = best_energy_correlation( + emel_log_energy, reference_log_energy, 25) + active_ratio_delta = abs( + float(emel_audio["active_ratio"]) - float(reference_audio["active_ratio"])) + + reasons = [] + if len(emel_input) != args.frames or len(ref_input) != args.frames: + reasons.append("input frame count mismatch") + if len(emel_output) != args.frames or len(ref_output) != args.frames: + reasons.append("output frame count mismatch") + if input_match != 1.0: + reasons.append(f"same-WAV input token match is {input_match:.6f}, expected 1.0") + if output_match < args.min_output_match: + reasons.append( + f"output token match {output_match:.6f} below {args.min_output_match:.6f}") + if first_four_match < args.min_first_four_match: + reasons.append( + f"first-four token match {first_four_match:.6f} below " + f"{args.min_first_four_match:.6f}") + if energy_correlation < args.min_energy_correlation: + reasons.append( + f"energy correlation {energy_correlation:.6f} below " + f"{args.min_energy_correlation:.6f}") + if active_ratio_delta > args.max_active_ratio_delta: + reasons.append( + f"active ratio delta {active_ratio_delta:.6f} above " + f"{args.max_active_ratio_delta:.6f}") + if float(emel_audio["rms"]) <= 0.0 or float(reference_audio["rms"]) <= 0.0: + reasons.append("one or both output WAVs are silent") + + report = { + "surface": "personaplex_compare/v1", + "status": "pass" if not reasons else "fail", + "reasons": reasons, + "cpu_threads": args.threads, + "seed": args.seed, + "frames": args.frames, + "inference": { + "path": str(inference_path.resolve()), + "sha256": sha256(inference_path), + "public_n_q": public_n_q, + "max_blocks": max_blocks, + "block_tokens": block_tokens, + "prompt_text_token": prompt_text_token, + "frame_samples": frame_samples, + }, + "input": { + "path": str(Path(args.audio).resolve()), + "sha256": sha256(Path(args.audio)), + "emel_frames": len(emel_input), + "reference_frames": len(ref_input), + "audio_frames": audio_input_frames, + "compared_public_tokens": audio_input_frames * public_n_q, + "public_codebook_match_fraction": input_match, + }, + "tokens": { + "emel_output_frames": len(emel_output), + "reference_output_frames": len(ref_output), + "common_prefix_tokens": common_token_prefix(emel_output, ref_output), + "public_codebook_match_fraction": output_match, + "first_four_codebook_match_fraction": first_four_match, + "text_token_match_fraction": text_match, + }, + "audio": { + "emel": emel_audio, + "reference": reference_audio, + "best_log_energy_correlation": energy_correlation, + "best_energy_lag_frames_80ms": energy_lag, + "active_ratio_delta": active_ratio_delta, + "emel_wav": str(emel_wav.resolve()), + "reference_wav": str(reference_wav.resolve()), + "emel_sha256": sha256(emel_wav), + "reference_sha256": sha256(reference_wav), + }, + "timing": { + "emel_wall_seconds": emel_elapsed, + "reference_wall_seconds": reference_elapsed, + "reference_over_emel": reference_elapsed / emel_elapsed, + }, + } + report_path = output_dir / "personaplex_compare.json" + report_path.write_text(json.dumps(report, indent=2) + "\n") + print(json.dumps(report, indent=2)) + print(f"report: {report_path.resolve()}") + return 0 if not reasons else 1 + + +if __name__ == "__main__": + try: + sys.exit(main()) + except (OSError, RuntimeError, ValueError) as error: + sys.exit(f"error: {error}") diff --git a/tools/bench/personaplex_compare_tests.cpp b/tools/bench/personaplex_compare_tests.cpp new file mode 100644 index 00000000..2cd0ecf4 --- /dev/null +++ b/tools/bench/personaplex_compare_tests.cpp @@ -0,0 +1,157 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN + +#include +#include +#include +#include + +#include + +#if !defined(_WIN32) +#include +#endif + +namespace { + +std::filesystem::path repo_root() { +#ifdef BENCH_REPO_ROOT + return BENCH_REPO_ROOT; +#else + return std::filesystem::current_path(); +#endif +} + +std::filesystem::path compare_script_path() { +#ifdef PERSONAPLEX_COMPARE_SCRIPT_PATH + return PERSONAPLEX_COMPARE_SCRIPT_PATH; +#else + return repo_root() / "tools" / "bench" / "personaplex_compare.py"; +#endif +} + +std::string read_file(const std::filesystem::path &path) { + std::ifstream input(path, std::ios::binary); + if (!input.good()) { + return {}; + } + return std::string(std::istreambuf_iterator(input), + std::istreambuf_iterator()); +} + +std::string quote_arg_posix(const std::string &arg) { + std::string output = "'"; + for (const char value : arg) { + if (value == '\'') { + output += "'\\''"; + } else { + output.push_back(value); + } + } + output += "'"; + return output; +} + +int command_exit_code(const std::string &command) { + const int status = std::system(command.c_str()); + if (status == -1) { + return -1; + } +#if defined(_WIN32) + return status; +#else + return WIFEXITED(status) ? WEXITSTATUS(status) : -1; +#endif +} + +} // namespace + +TEST_CASE("personaplex compare math reports exact and partial token behavior") { + const std::string module = quote_arg_posix(compare_script_path().string()); + const std::string program = + "import importlib.util; " + "spec=importlib.util.spec_from_file_location('personaplex_compare', " + + module + + "); m=importlib.util.module_from_spec(spec); spec.loader.exec_module(m); " + "assert m.match_fraction([[1,2],[3,4]], [[1,2],[3,4]], 2) == 1.0; " + "assert m.match_fraction([[1,9]], [[1,2]], 2) == 0.5; " + "assert m.common_token_prefix([[1,2]], [[1,3]]) == 1; " + "assert abs(m.correlation([1.0,2.0,3.0], [2.0,4.0,6.0])-1.0) < 1e-12"; + CHECK(command_exit_code("python3 -c " + quote_arg_posix(program)) == 0); +} + +TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { + const std::string compare_source = read_file(compare_script_path()); + const std::string wrapper_source = + read_file(repo_root() / "scripts" / "bench_personaplex_compare.sh"); + const std::string cmake_source = + read_file(repo_root() / "tools" / "bench" / "CMakeLists.txt"); + const std::string emel_source = + read_file(repo_root() / "tools" / "bench" / "speech" / + "personaplex_emel_runner.cpp"); + const std::string setup_source = + read_file(repo_root() / "scripts" / "setup_moshi_cpp_reference.sh"); + const std::string converter_source = + read_file(repo_root() / "tools" / "bench" / "moshi_gguf_convert.py"); + const std::string inference_source = + read_file(repo_root() / "tools" / "bench" / "personaplex-inference.json"); + + const std::size_t first_public_match = + compare_source.find("public_codebook_match_fraction"); + REQUIRE(first_public_match != std::string::npos); + CHECK(compare_source.find("public_codebook_match_fraction", + first_public_match + 1u) != std::string::npos); + CHECK(compare_source.find("best_log_energy_correlation") != + std::string::npos); + CHECK(compare_source.find("reference_over_emel") != std::string::npos); + CHECK(wrapper_source.find("--threads \"$THREADS\"") != std::string::npos); + CHECK(wrapper_source.find("--audio \"$AUDIO\"") != std::string::npos); + CHECK(wrapper_source.find("--inference-config \"$INFERENCE_CONFIG\"") != + std::string::npos); + CHECK(wrapper_source.find("--data-format=LEI16@24000") != std::string::npos); + CHECK(wrapper_source.find("mimi-e351c8d8-125-personaplex-emel.gguf") != + std::string::npos); + CHECK(wrapper_source.find("Hey, I'm Gabe. How are you doing?") != + std::string::npos); + CHECK(cmake_source.find("set(GGML_METAL OFF CACHE BOOL \"CPU-only " + "PersonaPlex reference lane\" FORCE)") != + std::string::npos); + CHECK(emel_source.find("#include --audio <24 kHz mono s16 wav> [--n-q N] // decode --mimi --codes --out // [--n-q N] +// personaplex --config --lm --mimi +// --voice --audio <24 kHz mono s16 wav> +// --out --frames --seed [--n-q N] +#include #include +#include #include #include +#include #include #include #include +#include #include #include #include @@ -92,13 +99,56 @@ bool load_wav_24khz_mono(const std::filesystem::path &path, return true; } +void write_u16_le(std::ofstream &out, const uint16_t value) { + out.write(reinterpret_cast(&value), sizeof(value)); +} + +void write_u32_le(std::ofstream &out, const uint32_t value) { + out.write(reinterpret_cast(&value), sizeof(value)); +} + +bool write_wav_24khz_mono(const std::filesystem::path &path, + const std::vector &pcm) { + std::ofstream out(path, std::ios::binary); + if (!out.good() || pcm.size() > (std::numeric_limits::max() / 2u)) { + return false; + } + const uint32_t data_bytes = static_cast(pcm.size() * 2u); + out.write("RIFF", 4); + write_u32_le(out, 36u + data_bytes); + out.write("WAVEfmt ", 8); + write_u32_le(out, 16u); + write_u16_le(out, 1u); + write_u16_le(out, 1u); + write_u32_le(out, 24000u); + write_u32_le(out, 48000u); + write_u16_le(out, 2u); + write_u16_le(out, 16u); + out.write("data", 4); + write_u32_le(out, data_bytes); + for (const float sample : pcm) { + const float clipped = std::max(-1.0f, std::min(1.0f, sample)); + const int16_t s16 = static_cast(std::lrint(clipped * 32767.0f)); + out.write(reinterpret_cast(&s16), sizeof(s16)); + } + return out.good(); +} + struct options { std::string command = {}; + std::filesystem::path config = {}; + std::filesystem::path lm = {}; std::filesystem::path mimi = {}; + std::filesystem::path voice = {}; std::filesystem::path audio = {}; std::filesystem::path codes = {}; std::filesystem::path out = {}; int n_q = 16; + int frames = 0; + int threads = 0; + unsigned int seed = 0u; + float audio_temperature = 0.8f; + float text_temperature = 0.7f; }; bool parse_options(const int argc, char **argv, options &opts) { @@ -109,8 +159,14 @@ bool parse_options(const int argc, char **argv, options &opts) { for (int index = 2; index < argc; ++index) { const std::string_view arg = argv[index]; const bool has_value = index + 1 < argc; - if (arg == "--mimi" && has_value) { + if (arg == "--config" && has_value) { + opts.config = argv[++index]; + } else if (arg == "--lm" && has_value) { + opts.lm = argv[++index]; + } else if (arg == "--mimi" && has_value) { opts.mimi = argv[++index]; + } else if (arg == "--voice" && has_value) { + opts.voice = argv[++index]; } else if (arg == "--audio" && has_value) { opts.audio = argv[++index]; } else if (arg == "--codes" && has_value) { @@ -119,6 +175,17 @@ bool parse_options(const int argc, char **argv, options &opts) { opts.out = argv[++index]; } else if (arg == "--n-q" && has_value) { opts.n_q = std::atoi(argv[++index]); + } else if (arg == "--frames" && has_value) { + opts.frames = std::atoi(argv[++index]); + } else if (arg == "--threads" && has_value) { + opts.threads = std::atoi(argv[++index]); + } else if (arg == "--seed" && has_value) { + opts.seed = + static_cast(std::strtoul(argv[++index], nullptr, 10)); + } else if (arg == "--audio-temperature" && has_value) { + opts.audio_temperature = std::strtof(argv[++index], nullptr); + } else if (arg == "--text-temperature" && has_value) { + opts.text_temperature = std::strtof(argv[++index], nullptr); } else { std::fprintf(stderr, "unknown or incomplete argument: %.*s\n", static_cast(arg.size()), arg.data()); @@ -128,7 +195,12 @@ bool parse_options(const int argc, char **argv, options &opts) { return (opts.command == "encode" && !opts.mimi.empty() && !opts.audio.empty()) || (opts.command == "decode" && !opts.mimi.empty() && - !opts.codes.empty() && !opts.out.empty()); + !opts.codes.empty() && !opts.out.empty()) || + (opts.command == "personaplex" && !opts.config.empty() && + !opts.lm.empty() && !opts.mimi.empty() && !opts.voice.empty() && + !opts.audio.empty() && !opts.out.empty() && opts.frames > 0 && + opts.threads > 0 && opts.seed > 0u && opts.n_q > 0 && + opts.audio_temperature > 0.0f && opts.text_temperature > 0.0f); } bool parse_codes_file(const std::filesystem::path &path, const int n_q, @@ -157,6 +229,125 @@ bool parse_codes_file(const std::filesystem::path &path, const int n_q, return !frames_out.empty(); } +int run_personaplex(const options &opts, ggml_backend_t backend_cpu) { + std::srand(opts.seed); + moshi_context_t *moshi = moshi_alloc(backend_cpu, backend_cpu); + if (moshi == nullptr) { + std::fprintf(stderr, "failed to allocate moshi context\n"); + return 1; + } + moshi_config_t config{}; + if (moshi_get_config(&config, opts.config.string().c_str()) != 0) { + std::fprintf(stderr, "failed to load PersonaPlex config: %s\n", + opts.config.string().c_str()); + return 1; + } + moshi_lm_t *lm = + moshi_lm_from_files(moshi, &config, opts.lm.string().c_str()); + if (lm == nullptr) { + std::fprintf(stderr, "failed to allocate PersonaPlex language model\n"); + return 1; + } + moshi_lm_gen_t *generator = moshi_lm_generator(lm); + mimi_codec_t *codec = mimi_alloc(moshi, opts.mimi.string().c_str(), opts.n_q); + if (generator == nullptr || codec == nullptr || moshi_lm_load(lm) != 0) { + std::fprintf(stderr, "failed to load PersonaPlex reference models\n"); + return 1; + } + mimi_encode_context_t *encoder = mimi_encode_alloc_context(codec); + mimi_decode_context_t *decoder = mimi_decode_alloc_context(codec); + if (encoder == nullptr || decoder == nullptr || + moshi_lm_personaplex_load_voice(moshi, generator, + opts.voice.string().c_str()) != 0) { + std::fprintf(stderr, "failed to initialize PersonaPlex voice/runtime\n"); + return 1; + } + + std::vector pcm = {}; + if (!load_wav_24khz_mono(opts.audio, pcm)) { + std::fprintf(stderr, "failed to load 24 kHz mono s16 wav: %s\n", + opts.audio.string().c_str()); + return 1; + } + const int frame_size = mimi_frame_size(codec); + if (frame_size <= 0) { + std::fprintf(stderr, "invalid Mimi frame size\n"); + return 1; + } + const size_t input_frames = + (pcm.size() + static_cast(frame_size) - 1u) / + static_cast(frame_size); + if (input_frames > static_cast(opts.frames)) { + std::fprintf(stderr, "invalid frame count for input audio\n"); + return 1; + } + + moshi_lm_start(moshi, generator, opts.audio_temperature, + opts.text_temperature); + std::vector input_frame(static_cast(frame_size), 0.0f); + std::vector decoded_frame(static_cast(frame_size), 0.0f); + std::vector output_pcm = {}; + output_pcm.reserve(static_cast(opts.frames) * + static_cast(frame_size)); + std::vector tokens(static_cast(opts.n_q), -1); + int text_token = -1; + const auto started = std::chrono::steady_clock::now(); + for (int frame = 0; frame < opts.frames; ++frame) { + std::fill(input_frame.begin(), input_frame.end(), 0.0f); + if (static_cast(frame) < input_frames) { + const size_t begin = + static_cast(frame) * static_cast(frame_size); + const size_t count = + std::min(static_cast(frame_size), pcm.size() - begin); + std::copy_n(pcm.data() + begin, count, input_frame.data()); + } + mimi_encode_send(encoder, input_frame.data()); + mimi_encode_receive(encoder, tokens.data()); + std::printf("input frame=%d codes=", frame); + for (size_t stream = 0; stream < tokens.size(); ++stream) { + std::printf("%s%d", stream == 0u ? "" : ",", + static_cast(tokens[stream])); + } + std::printf("\n"); + + moshi_lm_send2(generator, tokens); + const int produced = moshi_lm_receive(generator, text_token, tokens); + if (produced != 0) { + std::printf("output frame=%d text=%d codes=", frame, text_token); + for (size_t stream = 0; stream < tokens.size(); ++stream) { + std::printf("%s%d", stream == 0u ? "" : ",", + static_cast(tokens[stream])); + } + std::printf("\n"); + mimi_decode_send(decoder, tokens.data()); + mimi_decode_receive(decoder, decoded_frame.data()); + output_pcm.insert(output_pcm.end(), decoded_frame.begin(), + decoded_frame.end()); + } + } + const double elapsed = + std::chrono::duration(std::chrono::steady_clock::now() - started) + .count(); + if (output_pcm.empty() || !write_wav_24khz_mono(opts.out, output_pcm)) { + std::fprintf(stderr, "failed to write PersonaPlex output wav: %s\n", + opts.out.string().c_str()); + return 1; + } + std::fprintf(stderr, + "personaplex frames=%d output_frames=%zu seed=%u seconds=%.3f " + "frames_per_second=%.6f output=%s\n", + opts.frames, output_pcm.size() / static_cast(frame_size), + opts.seed, elapsed, static_cast(opts.frames) / elapsed, + opts.out.string().c_str()); + unref(decoder); + unref(encoder); + unref(codec); + unref(generator); + unref(lm); + unref(moshi); + return 0; +} + } // namespace int main(int argc, char **argv) { @@ -167,7 +358,11 @@ int main(int argc, char **argv) { " moshi_reference_driver encode --mimi --audio " "[--n-q N]\n" " moshi_reference_driver decode --mimi --codes " - "--out [--n-q N]\n"); + "--out [--n-q N]\n" + " moshi_reference_driver personaplex --config " + "--lm --mimi --voice --audio " + "--out --frames --threads --seed " + "[--n-q N]\n"); return 2; } @@ -176,6 +371,14 @@ int main(int argc, char **argv) { std::fprintf(stderr, "failed to init ggml cpu backend\n"); return 1; } + if (opts.threads > 0) { + ggml_backend_cpu_set_n_threads(backend_cpu, opts.threads); + } + if (opts.command == "personaplex") { + const int status = run_personaplex(opts, backend_cpu); + ggml_backend_free(backend_cpu); + return status; + } moshi_context_t *moshi = moshi_alloc(backend_cpu, backend_cpu); if (moshi == nullptr) { std::fprintf(stderr, "failed to alloc moshi context\n"); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp new file mode 100644 index 00000000..d717fce1 --- /dev/null +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -0,0 +1,626 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "emel/error/error.hpp" +#include "emel/gguf/loader/detail.hpp" +#include "emel/gguf/loader/events.hpp" +#include "emel/gguf/loader/sm.hpp" +#include "emel/model/data.hpp" +#include "emel/model/detail.hpp" +#include "emel/speech/codec/mimi/any.hpp" +#include "emel/speech/generator/moshi/personaplex/session/any.hpp" + +namespace { + +namespace mimi = emel::speech::codec::mimi; +namespace personaplex_session = + emel::speech::generator::moshi::personaplex::session; + +struct runner_config { + const char *mimi_path = nullptr; + const char *lm_path = nullptr; + const char *voice_path = nullptr; + const char *input_path = nullptr; + const char *output_path = nullptr; + size_t target_output_frames = 0; + uint32_t sampling_seed = 0; + float audio_temperature = 0.0f; + float text_temperature = 0.0f; + int32_t audio_top_k = 0; + int32_t text_top_k = 0; + int32_t max_blocks = 0; + int32_t block_tokens = 0; + int32_t prompt_text_token = 0; +}; + +void noop_probe_done(const emel::gguf::loader::events::probe_done &) {} +void noop_probe_error(const emel::gguf::loader::events::probe_error &) {} +void noop_bind_done(const emel::gguf::loader::events::bind_done &) {} +void noop_bind_error(const emel::gguf::loader::events::bind_error &) {} +void noop_parse_done(const emel::gguf::loader::events::parse_done &) {} +void noop_parse_error(const emel::gguf::loader::events::parse_error &) {} + +struct loaded_model { + std::vector file_bytes = {}; + std::vector kv_arena = {}; + std::vector kv_entries = {}; + std::unique_ptr model = {}; +}; + +struct streaming_cache { + std::vector key_cache = {}; + std::vector value_cache = {}; + std::vector layer_offsets = {}; + int32_t offset = 0; +}; + +bool read_binary_file(const std::filesystem::path &path, + std::vector &bytes_out) { + std::ifstream file{path, std::ios::binary}; + if (!file.good()) { + return false; + } + file.seekg(0, std::ios::end); + const std::streamoff size = file.tellg(); + if (size <= 0) { + return false; + } + file.seekg(0, std::ios::beg); + bytes_out.resize(static_cast(size)); + file.read(reinterpret_cast(bytes_out.data()), size); + return file.good(); +} + +bool materialize_tensor_names(emel::model::data &model, + const std::vector &file) { + model.name_bytes_used = 0; + for (uint32_t index = 0; index < model.n_tensors; ++index) { + auto &tensor = model.tensors[index]; + const size_t source_offset = static_cast(tensor.name_offset); + const size_t length = static_cast(tensor.name_length); + if (source_offset + length > file.size() || + static_cast(model.name_bytes_used) + length > + model.name_storage.size()) { + return false; + } + std::copy_n(file.data() + source_offset, length, + model.name_storage.data() + model.name_bytes_used); + tensor.name_offset = model.name_bytes_used; + model.name_bytes_used += static_cast(length); + } + return true; +} + +bool load_model(const std::filesystem::path &path, loaded_model &loaded) { + loaded = {}; + loaded.model = std::make_unique(); + if (!read_binary_file(path, loaded.file_bytes)) { + std::fprintf(stderr, "failed to read model: %s\n", path.string().c_str()); + return false; + } + + emel::gguf::loader::sm loader{}; + emel::gguf::loader::requirements requirements{}; + if (!loader.process_event(emel::gguf::loader::event::probe{ + std::span{loaded.file_bytes}, + requirements, + emel::gguf::loader::event::probe_done_fn::from<&noop_probe_done>(), + emel::gguf::loader::event::probe_error_fn::from<&noop_probe_error>(), + }) || + requirements.tensor_count > loaded.model->tensors.size()) { + std::fprintf(stderr, "failed to probe model: %s\n", path.string().c_str()); + return false; + } + + const uint64_t arena_bytes = + emel::gguf::loader::detail::required_kv_arena_bytes(requirements); + if (arena_bytes == std::numeric_limits::max()) { + return false; + } + loaded.kv_arena.resize(static_cast(arena_bytes)); + loaded.kv_entries.resize(requirements.kv_count); + loaded.model->n_tensors = requirements.tensor_count; + + if (!loader.process_event(emel::gguf::loader::event::bind_storage{ + std::span{loaded.kv_arena}, + std::span{loaded.kv_entries}, + std::span{ + loaded.model->tensors.data(), loaded.model->n_tensors}, + emel::gguf::loader::event::bind_done_fn::from<&noop_bind_done>(), + emel::gguf::loader::event::bind_error_fn::from<&noop_bind_error>(), + }) || + !loader.process_event(emel::gguf::loader::event::parse{ + std::span{loaded.file_bytes}, + emel::gguf::loader::event::parse_done_fn::from<&noop_parse_done>(), + emel::gguf::loader::event::parse_error_fn::from<&noop_parse_error>(), + })) { + std::fprintf(stderr, "failed to parse model: %s\n", path.string().c_str()); + return false; + } + + const emel::model::detail::kv_binding binding{ + .arena = std::span{loaded.kv_arena}, + .entries = + std::span{loaded.kv_entries}, + }; + if (!emel::model::detail::load_hparams_from_gguf(binding, *loaded.model)) { + std::fprintf(stderr, "failed to load hparams: %s\n", path.string().c_str()); + return false; + } + loaded.model->weights_data = loaded.file_bytes.data(); + loaded.model->weights_size = loaded.file_bytes.size(); + return materialize_tensor_names(*loaded.model, loaded.file_bytes); +} + +uint16_t read_u16_le(const uint8_t *data) { + uint16_t value = 0; + std::memcpy(&value, data, sizeof(value)); + return value; +} + +uint32_t read_u32_le(const uint8_t *data) { + uint32_t value = 0; + std::memcpy(&value, data, sizeof(value)); + return value; +} + +bool load_wav_24khz_mono_s16(const std::filesystem::path &path, + std::vector &pcm_out) { + std::vector bytes = {}; + if (!read_binary_file(path, bytes) || bytes.size() < 44 || + std::memcmp(bytes.data(), "RIFF", 4) != 0 || + std::memcmp(bytes.data() + 8, "WAVE", 4) != 0) { + return false; + } + + uint16_t format = 0; + uint16_t channels = 0; + uint32_t sample_rate = 0; + uint16_t bits = 0; + size_t data_offset = 0; + size_t data_size = 0; + size_t offset = 12; + while (offset + 8 <= bytes.size()) { + const uint8_t *chunk = bytes.data() + offset; + const uint32_t chunk_size = read_u32_le(chunk + 4); + const size_t payload = offset + 8; + if (payload + chunk_size > bytes.size()) { + return false; + } + if (std::memcmp(chunk, "fmt ", 4) == 0 && chunk_size >= 16) { + format = read_u16_le(bytes.data() + payload); + channels = read_u16_le(bytes.data() + payload + 2); + sample_rate = read_u32_le(bytes.data() + payload + 4); + bits = read_u16_le(bytes.data() + payload + 14); + } else if (std::memcmp(chunk, "data", 4) == 0) { + data_offset = payload; + data_size = chunk_size; + } + offset = payload + chunk_size + (chunk_size & 1u); + } + if (format != 1 || channels != 1 || sample_rate != 24000 || bits != 16 || + data_offset == 0 || data_size == 0) { + return false; + } + + const size_t samples = data_size / sizeof(int16_t); + pcm_out.resize(samples); + for (size_t index = 0; index < samples; ++index) { + int16_t sample = 0; + std::memcpy(&sample, bytes.data() + data_offset + index * sizeof(sample), + sizeof(sample)); + pcm_out[index] = static_cast(sample) / 32768.0f; + } + return true; +} + +void write_u16_le(std::ofstream &out, const uint16_t value) { + out.write(reinterpret_cast(&value), sizeof(value)); +} + +void write_u32_le(std::ofstream &out, const uint32_t value) { + out.write(reinterpret_cast(&value), sizeof(value)); +} + +bool write_wav_24khz_mono_s16(const std::filesystem::path &path, + const std::span pcm) { + std::ofstream out{path, std::ios::binary}; + if (!out.good()) { + return false; + } + const uint32_t data_bytes = static_cast(pcm.size() * 2u); + out.write("RIFF", 4); + write_u32_le(out, 36u + data_bytes); + out.write("WAVEfmt ", 8); + write_u32_le(out, 16u); + write_u16_le(out, 1u); + write_u16_le(out, 1u); + write_u32_le(out, 24000u); + write_u32_le(out, 24000u * 2u); + write_u16_le(out, 2u); + write_u16_le(out, 16u); + out.write("data", 4); + write_u32_le(out, data_bytes); + for (const float sample : pcm) { + const float clipped = std::max(-1.0f, std::min(1.0f, sample)); + const int16_t s16 = static_cast(std::lrint(clipped * 32767.0f)); + out.write(reinterpret_cast(&s16), sizeof(s16)); + } + return out.good(); +} + +bool prepare_streaming_cache(streaming_cache &cache, const int32_t layer_count, + const int32_t position_capacity, + const int32_t kv_dim) { + if (layer_count <= 0 || position_capacity <= 0 || kv_dim <= 0) { + return false; + } + const size_t per_layer = + static_cast(position_capacity) * static_cast(kv_dim); + cache.layer_offsets.resize(static_cast(layer_count)); + for (int32_t layer = 0; layer < layer_count; ++layer) { + cache.layer_offsets[static_cast(layer)] = + static_cast(layer) * per_layer; + } + cache.key_cache.assign(static_cast(layer_count) * per_layer, 0u); + cache.value_cache.assign(cache.key_cache.size(), 0u); + cache.offset = 0; + return true; +} + +} // namespace + +int main(int argc, char **argv) { + if (argc != 15) { + std::fprintf(stderr, + "usage: %s " + " " + " " + " " + "\n", + argv[0]); + return 2; + } + + char *target_end = nullptr; + const unsigned long parsed_target = std::strtoul(argv[6], &target_end, 10); + if (target_end == argv[6] || *target_end != '\0' || parsed_target == 0) { + std::fprintf(stderr, "target output frames must be a positive integer\n"); + return 2; + } + char *seed_end = nullptr; + const unsigned long parsed_seed = std::strtoul(argv[7], &seed_end, 10); + char *audio_temperature_end = nullptr; + const float parsed_audio_temperature = + std::strtof(argv[8], &audio_temperature_end); + char *text_temperature_end = nullptr; + const float parsed_text_temperature = + std::strtof(argv[9], &text_temperature_end); + char *audio_top_k_end = nullptr; + const long parsed_audio_top_k = std::strtol(argv[10], &audio_top_k_end, 10); + char *text_top_k_end = nullptr; + const long parsed_text_top_k = std::strtol(argv[11], &text_top_k_end, 10); + char *max_blocks_end = nullptr; + const long parsed_max_blocks = std::strtol(argv[12], &max_blocks_end, 10); + char *block_tokens_end = nullptr; + const long parsed_block_tokens = std::strtol(argv[13], &block_tokens_end, 10); + char *prompt_text_token_end = nullptr; + const long parsed_prompt_text_token = + std::strtol(argv[14], &prompt_text_token_end, 10); + if (seed_end == argv[7] || *seed_end != '\0' || parsed_seed == 0 || + parsed_seed > std::numeric_limits::max() || + audio_temperature_end == argv[8] || *audio_temperature_end != '\0' || + parsed_audio_temperature <= 0.0f || text_temperature_end == argv[9] || + *text_temperature_end != '\0' || parsed_text_temperature <= 0.0f || + audio_top_k_end == argv[10] || *audio_top_k_end != '\0' || + parsed_audio_top_k <= 0 || + parsed_audio_top_k > std::numeric_limits::max() || + text_top_k_end == argv[11] || *text_top_k_end != '\0' || + parsed_text_top_k <= 0 || + parsed_text_top_k > std::numeric_limits::max() || + max_blocks_end == argv[12] || *max_blocks_end != '\0' || + parsed_max_blocks <= 0 || + parsed_max_blocks > std::numeric_limits::max() || + block_tokens_end == argv[13] || *block_tokens_end != '\0' || + parsed_block_tokens <= 0 || + parsed_block_tokens > std::numeric_limits::max() || + prompt_text_token_end == argv[14] || *prompt_text_token_end != '\0' || + parsed_prompt_text_token < std::numeric_limits::min() || + parsed_prompt_text_token > std::numeric_limits::max()) { + std::fprintf(stderr, "invalid sampling configuration\n"); + return 2; + } + const runner_config config{ + .mimi_path = argv[1], + .lm_path = argv[2], + .voice_path = argv[3], + .input_path = argv[4], + .output_path = argv[5], + .target_output_frames = static_cast(parsed_target), + .sampling_seed = static_cast(parsed_seed), + .audio_temperature = parsed_audio_temperature, + .text_temperature = parsed_text_temperature, + .audio_top_k = static_cast(parsed_audio_top_k), + .text_top_k = static_cast(parsed_text_top_k), + .max_blocks = static_cast(parsed_max_blocks), + .block_tokens = static_cast(parsed_block_tokens), + .prompt_text_token = static_cast(parsed_prompt_text_token), + }; + + loaded_model mimi_model = {}; + loaded_model lm_model = {}; + loaded_model voice_model = {}; + if (!load_model(config.mimi_path, mimi_model) || + !load_model(config.lm_path, lm_model) || + !load_model(config.voice_path, voice_model)) { + return 1; + } + + std::vector input_pcm = {}; + if (!load_wav_24khz_mono_s16(config.input_path, input_pcm)) { + std::fprintf(stderr, "input must be 24 kHz mono s16 WAV: %s\n", + config.input_path); + return 1; + } + + const int32_t frame_samples_i32 = static_cast( + std::lround(static_cast(mimi_model.model->mimi.sample_rate) / + static_cast(mimi_model.model->mimi.frame_rate))); + const int32_t public_n_q = lm_model.model->moshi_lm.inference_dep_q; + if (frame_samples_i32 <= 0 || public_n_q <= 0 || + public_n_q != mimi_model.model->mimi.n_q || + mimi_model.model->mimi.card != lm_model.model->moshi_lm.card) { + std::fprintf(stderr, "invalid PersonaPlex/Mimi model contract\n"); + return 1; + } + const size_t frame_samples = static_cast(frame_samples_i32); + const size_t input_frames = + (input_pcm.size() + frame_samples - 1u) / frame_samples; + if (input_frames > config.target_output_frames) { + std::fprintf(stderr, + "input requires %zu frames, exceeding target output %zu\n", + input_frames, config.target_output_frames); + return 1; + } + + std::vector encoder_prepared( + mimi::prepared_arena_floats(*mimi_model.model)); + std::vector encoder_state(mimi::state_arena_floats(*mimi_model.model)); + std::vector encoder_workspace( + mimi::workspace_arena_floats(*mimi_model.model)); + std::vector encoder_frame(mimi::frame_arena_floats(*mimi_model.model)); + std::vector decoder_prepared( + mimi::prepared_arena_floats(*mimi_model.model)); + std::vector decoder_state(mimi::state_arena_floats(*mimi_model.model)); + std::vector decoder_workspace( + mimi::workspace_arena_floats(*mimi_model.model)); + std::vector decoder_frame(mimi::frame_arena_floats(*mimi_model.model)); + streaming_cache temporal_cache = {}; + streaming_cache depformer_cache = {}; + if (!prepare_streaming_cache( + temporal_cache, lm_model.model->moshi_lm.num_layers, + lm_model.model->moshi_lm.context, lm_model.model->moshi_lm.dim) || + !prepare_streaming_cache(depformer_cache, + lm_model.model->moshi_lm.depformer_num_layers, + lm_model.model->moshi_lm.depformer_context, + lm_model.model->moshi_lm.depformer_dim)) { + std::fprintf(stderr, "failed to allocate Moshi streaming caches\n"); + return 1; + } + + std::vector pcm_frame(frame_samples, 0.0f); + std::vector output_pcm(config.target_output_frames * frame_samples, + 0.0f); + std::vector input_codes(static_cast(public_n_q), -1); + std::vector output_codes(static_cast(public_n_q), -1); + + personaplex_session::dependencies session_dependencies{ + .temporal_kv = + { + .key_cache = std::span{temporal_cache.key_cache}, + .value_cache = std::span{temporal_cache.value_cache}, + .layer_cache_offsets = + std::span{temporal_cache.layer_offsets}, + .offset = &temporal_cache.offset, + .layer_count = lm_model.model->moshi_lm.num_layers, + .position_capacity = lm_model.model->moshi_lm.context, + .block_tokens = 1, + .kv_dim = lm_model.model->moshi_lm.dim, + }, + .depformer_kv = + { + .key_cache = std::span{depformer_cache.key_cache}, + .value_cache = std::span{depformer_cache.value_cache}, + .layer_cache_offsets = + std::span{depformer_cache.layer_offsets}, + .offset = &depformer_cache.offset, + .layer_count = lm_model.model->moshi_lm.depformer_num_layers, + .position_capacity = lm_model.model->moshi_lm.depformer_context, + .block_tokens = 1, + .kv_dim = lm_model.model->moshi_lm.depformer_dim, + }, + .generator_memory = emel::memory::hybrid::kv_binding{}, + }; + personaplex_session::sm session{session_dependencies}; + emel::error::type session_err = + emel::error::cast(personaplex_session::error::none); + personaplex_session::event::initialize initialize{ + .mimi_model = *mimi_model.model, + .lm_model = *lm_model.model, + .voice_model = *voice_model.model, + .encoder_storage = + { + .prepared = std::span{encoder_prepared}, + .state = std::span{encoder_state}, + .workspace = std::span{encoder_workspace}, + .frame = std::span{encoder_frame}, + }, + .decoder_storage = + { + .prepared = std::span{decoder_prepared}, + .state = std::span{decoder_state}, + .workspace = std::span{decoder_workspace}, + .frame = std::span{decoder_frame}, + }, + .sampling = + { + .enabled = true, + .consume_forced_text = true, + .audio_temperature = config.audio_temperature, + .text_temperature = config.text_temperature, + .audio_top_k = config.audio_top_k, + .text_top_k = config.text_top_k, + .seed = config.sampling_seed, + }, + .max_blocks = config.max_blocks, + .block_tokens = config.block_tokens, + .error_out = session_err, + }; + if (!session.process_event(initialize)) { + std::fprintf(stderr, "PersonaPlex session initialize failed err=%d\n", + static_cast(session_err)); + return 1; + } + + while (session.is( + stateforward::sml::state)) { + session_err = emel::error::cast(personaplex_session::error::none); + personaplex_session::event::advance_voice advance{.error_out = session_err}; + (void)session.process_event(advance); + } + while (session.is( + stateforward::sml::state)) { + session_err = emel::error::cast(personaplex_session::error::none); + personaplex_session::event::advance_prompt advance{ + .text_token = config.prompt_text_token, + .error_out = session_err, + }; + (void)session.process_event(advance); + } + if (!session.is(stateforward::sml::state)) { + std::fprintf(stderr, "PersonaPlex prefill failed err=%d\n", + static_cast(session_err)); + return 1; + } + + for (size_t frame_index = 0; frame_index < input_frames; ++frame_index) { + std::fill(pcm_frame.begin(), pcm_frame.end(), 0.0f); + const size_t begin = frame_index * frame_samples; + const size_t copy_count = std::min(frame_samples, input_pcm.size() - begin); + std::copy_n(input_pcm.data() + begin, copy_count, pcm_frame.data()); + int32_t text_token = -1; + bool produced = false; + session_err = emel::error::cast(personaplex_session::error::none); + personaplex_session::event::live_frame frame{ + .payload = + { + .pcm = std::span{pcm_frame}, + .input_codes_out = std::span{input_codes}, + .output_codes_out = std::span{output_codes}, + .text_token_out = text_token, + .produced_out = produced, + .pcm_out = std::span{output_pcm.data() + + frame_index * frame_samples, + frame_samples}, + }, + .error_out = session_err, + }; + (void)session.process_event(frame); + std::fprintf(stderr, "EMEL_INPUT frame=%zu codes=", frame_index); + for (int32_t index = 0; index < public_n_q; ++index) { + std::fprintf(stderr, "%s%d", index == 0 ? "" : ",", + input_codes[static_cast(index)]); + } + std::fprintf(stderr, "\nEMEL_OUTPUT frame=%zu text=%d codes=", frame_index, + text_token); + for (int32_t index = 0; index < public_n_q; ++index) { + std::fprintf(stderr, "%s%d", index == 0 ? "" : ",", + output_codes[static_cast(index)]); + } + std::fprintf(stderr, "\n"); + } + + session_err = emel::error::cast(personaplex_session::error::none); + personaplex_session::event::begin_flush begin_flush{.error_out = session_err}; + (void)session.process_event(begin_flush); + std::fill(pcm_frame.begin(), pcm_frame.end(), 0.0f); + const size_t flush_steps = config.target_output_frames - input_frames; + for (size_t index = 0; index < flush_steps; ++index) { + const size_t frame_index = input_frames + index; + int32_t text_token = -1; + bool produced = false; + session_err = emel::error::cast(personaplex_session::error::none); + personaplex_session::event::flush_frame frame{ + .payload = + { + .pcm = std::span{pcm_frame}, + .input_codes_out = std::span{input_codes}, + .output_codes_out = std::span{output_codes}, + .text_token_out = text_token, + .produced_out = produced, + .pcm_out = std::span{output_pcm.data() + + frame_index * frame_samples, + frame_samples}, + }, + .error_out = session_err, + }; + (void)session.process_event(frame); + std::fprintf(stderr, "EMEL_INPUT frame=%zu codes=", frame_index); + for (int32_t codebook = 0; codebook < public_n_q; ++codebook) { + std::fprintf(stderr, "%s%d", codebook == 0 ? "" : ",", + input_codes[static_cast(codebook)]); + } + std::fprintf(stderr, "\nEMEL_OUTPUT frame=%zu text=%d codes=", frame_index, + text_token); + for (int32_t codebook = 0; codebook < public_n_q; ++codebook) { + std::fprintf(stderr, "%s%d", codebook == 0 ? "" : ",", + output_codes[static_cast(codebook)]); + } + std::fprintf(stderr, "\n"); + } + personaplex_session::event::finish finish{.error_out = session_err}; + (void)session.process_event(finish); + if (!session.is(stateforward::sml::state)) { + std::fprintf(stderr, "PersonaPlex session failed err=%d\n", + static_cast(session_err)); + return 1; + } + + if (output_pcm.empty()) { + std::fprintf(stderr, "no generated audio frames were produced\n"); + return 1; + } + + double energy = 0.0; + float peak = 0.0f; + for (const float sample : output_pcm) { + energy += static_cast(sample) * static_cast(sample); + peak = std::max(peak, std::abs(sample)); + } + const double rms = std::sqrt(energy / static_cast(output_pcm.size())); + if (!write_wav_24khz_mono_s16(config.output_path, + std::span{output_pcm})) { + std::fprintf(stderr, "failed to write output wav: %s\n", + config.output_path); + return 1; + } + + std::printf("input_frames=%zu output_frames=%zu output_seconds=%.3f " + "peak=%.6f rms=%.6f seed=%u output=%s\n", + input_frames, output_pcm.size() / frame_samples, + static_cast(output_pcm.size()) / 24000.0, peak, rms, + config.sampling_seed, config.output_path); + return 0; +} From 63e4dd3011296725335aba9fc89be1d5a2ec4ea7 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Thu, 9 Jul 2026 23:30:21 -0500 Subject: [PATCH 05/61] fix: match Moshi timestep RoPE arithmetic --- .../debug/moshi-personaplex-audio-parity.md | 330 ++++++++++++++++-- src/emel/kernel/aarch64/actions.hpp | 5 + src/emel/kernel/aarch64/guards.hpp | 46 ++- src/emel/kernel/aarch64/sm.hpp | 5 + src/emel/kernel/detail.hpp | 73 +++- src/emel/kernel/x86_64/actions.hpp | 5 + src/emel/kernel/x86_64/guards.hpp | 46 ++- src/emel/kernel/x86_64/sm.hpp | 5 + .../generator/moshi/executor/actions.hpp | 120 +++++-- .../speech/generator/moshi/executor/sm.hpp | 18 +- tests/kernel/lifecycle_tests.cpp | 36 ++ tests/kernel/test_helpers.hpp | 18 + tests/kernel/x86_64_tests.cpp | 23 +- 13 files changed, 629 insertions(+), 101 deletions(-) diff --git a/.planning/debug/moshi-personaplex-audio-parity.md b/.planning/debug/moshi-personaplex-audio-parity.md index e30a7b67..2325462f 100644 --- a/.planning/debug/moshi-personaplex-audio-parity.md +++ b/.planning/debug/moshi-personaplex-audio-parity.md @@ -10,25 +10,27 @@ updated: 2026-07-09 ## Symptoms - expected: EMEL and moshi.cpp consume the same macOS `say` WAV with seed 1234 and produce closely matching PersonaPlex speech audio and token behavior on CPU. -- actual: both CPU lanes now complete, emit non-silent speech WAVs, and follow the same - 51-frame voice plus 12-frame prompt setup. Seeded codec tokens are not sample-identical - after small arithmetic differences reorder stochastic winners. +- actual: both CPU lanes complete and emit non-silent speech, but the original moshi.cpp + reference run dropped 8,277 samples from the input WAV. Its prior output and the EMEL + schedule derived from it are not valid evidence of correct end-to-end input handling. - errors: none in the completed EMEL or CPU-only reference run. - timeline: implementation and E2E comparison are complete; scoped repository gates remain. - reproduction: run `build/emel_moshi_say_e2e_current` with the converted Mimi, Moshi LM, NATF0 voice, and `build/moshi_e2e/say_input_24k.wav` inputs. ## Current Focus -- hypothesis: resolved. The raw-logit shortcut, process-global RNG, Q4_K accumulation - grouping, and widened RMS square changed the seeded distribution path. -- test: focused arithmetic/actor regressions plus complete EMEL and Metal-free reference - runs from the same WAV and seed. -- expecting: matched phase counts and speech-turn behavior with close audio activity/level; - exact token identity is not expected once a stochastic winner differs. -- next_action: none for the runtime objective. The repository lint snapshot has unrelated - pre-existing drift and was not updated without user consent. -- reasoning_checkpoint: -- tdd_checkpoint: +- hypothesis: confirmed. Temporal timestep-embedding RoPE was the first divergent + arithmetic operation because EMEL contracted reference-separated f32 products into FMA. +- test: the captured frame-9/layer-26/head-9 pair now dispatches through the public CPU + kernel actor and requires reference bits `0x3f908001` / `0x3ea6cd3b`. +- result: the fresh unchanged-threshold 125-frame comparator passes with exact public + input, output, first-four, and text tokens plus effectively identical audio behavior. +- next_action: commit and push the guarded kernel route, public regression, maintained + comparison evidence, and audible 10-second WAV locations. +- reasoning_checkpoint: the causal chain is closed from one BF16 query rounding boundary + through raw scores, softmax, head output, sampled tokens, and decoded audio. +- tdd_checkpoint: the public kernel actor regression failed before the supported + split-layout route was implemented and passes with the reference arithmetic. ## Evidence @@ -92,6 +94,271 @@ updated: 2026-07-09 implication: implementation-specific gates are green. The global lint snapshot was intentionally not updated because project policy requires explicit user consent. +- timestamp: 2026-07-09T23:40:00-05:00 + observation: inspection and raw-sample comparison proved moshi.cpp's PersonaPlex file + loop fed only 88,320 of 96,597 samples to Mimi. A local reference-tool correction removed + the unsubmitted pre-read, preserved every pending resampler frame until consumption, and + flushed the padded tail exactly once. + implication: the previous reference WAV and its audio-envelope comparison are invalid; + matching the reference's broken PCM schedule was not correct same-WAV parity. + +- timestamp: 2026-07-09T23:45:00-05:00 + observation: two corrected CPU-only seed-1234 reference runs each consumed 51 PCM frames. + Frame checkpoints 0/15/30/45/50 exactly matched WAV samples + 0/28800/57600/86400/96000, and the two 10-second output WAVs were byte-identical with + SHA-256 9ee9b7f686b3911ddb42589a3220eb029b3c5f4d2bed0361aef6b8f75a1c9564. + implication: the corrected moshi.cpp reference now receives the complete WAV contiguously + and is deterministic; EMEL must be realigned before parity can be claimed. + +- timestamp: 2026-07-10T00:15:00-05:00 + observation: a new macOS Samantha utterance, `Hey, I'm Gabe. How are you doing?`, was + generated as 2.267208 seconds of mono 24 kHz s16 PCM. Corrected moshi.cpp consumed 29 + contiguous frames, including one padded tail frame, and emitted a 10-second CPU WAV. + implication: the comparison now uses a natural conversational input instead of the old + opaque utterance while preserving the same fixed-seed and model/voice contract. + +- timestamp: 2026-07-10T00:25:00-05:00 + observation: EMEL's runner was corrected to consume contiguous PCM from sample zero, + encode fresh zero-PCM frames through the streaming Mimi actor after EOF, and use an + injected 125-output-frame target. Runner dimensions/diagnostic phase now live in an + injected context rather than globals. It consumed 29 input plus 96 silence frames and + emitted exactly 125 output frames. + implication: both lanes now receive the same real PCM and streaming silence schedule; + EMEL no longer mirrors moshi.cpp's former dropped-frame bug or repeats the final speech + token frame during flush. + +- timestamp: 2026-07-10T00:35:00-05:00 + observation: both lanes are byte-deterministic across two seed-1234 runs. EMEL/reference + duration is 10.0/10.0 seconds, active-frame ratio is 47.2%/48.0%, RMS is + 0.06268/0.07828 (EMEL 1.93 dB quieter), and best 80 ms energy-envelope correlation is + 0.457 at an 11-frame lag. Raw text behavior shares the response onset `0,293` before + subsequent sampled tokens diverge. + implication: end-to-end input scheduling, output duration, activity, level, response + onset, and determinism now align on the organic utterance; exact stochastic token or + waveform parity remains unproven. + +- timestamp: 2026-07-10T01:05:00-05:00 + observation: current-source O0 and O3 frame-0 runs produce the same EMEL sequence + `1049,1770,19,...`; the CPU reference produces `1049,488,1632,...`, while the older Metal + reference starts `1049,1770,646,...`. + implication: compiler optimization is eliminated. Voice-prefill frame 0 is + input-independent and already diverges from the required CPU lane at codebook 1. + +- timestamp: 2026-07-10T01:10:00-05:00 + observation: the post-Q4-order artifact predates the RMS change and produced + `1049,488,...`; its temporal output begins + `-0.180639,0.082387,0.385717`, close to CPU reference + `-0.186217,0.083980,0.380608` and far from Metal reference + `-0.060614,0.170016,0.397496`. The Q4 artifact already used the final separate + `sum -= minimum; sum += dot` accumulation order. + implication: the Q4 accumulation fix is not the chronological cause of the later + codebook-1 switch. The subsequent RMS float-square-order change is the only remaining + numeric pivot in that commit, although its local arithmetic matches GGML CPU source and + must not be reverted solely from a sampled-token coincidence. + +- timestamp: 2026-07-10T01:15:00-05:00 + observation: the existing RMS and Q4 regressions call detail helpers directly. They prove + isolated arithmetic but do not exercise the maintained actor dispatch path or compounded + temporal/depformer graph. + implication: the next failing regression must dispatch a captured earliest unequal + operand through `emel::kernel::sm::process_event`, or run the pinned frame-0 contract + through `moshi_executor::sm::process_event`, without adding test-only production hooks. + +- timestamp: 2026-07-09T19:45:00-05:00 + observation: full layer-0 array dumps are bit-equal through norm2 and the 22,528-value + Q4_K gating projection. The first unequal byte is gated element 13, where CPU GGML's + AArch64 vector SiLU returns `0xbe3c4e19` and EMEL's scalar `std::exp` route returns + `0xbe3c4e18`. + implication: Q4_K is eliminated as the earliest frame-0 mismatch; AArch64 SiLU routing is + the first authoritative divergent operand. + +- timestamp: 2026-07-09T19:55:00-05:00 + observation: an actor-level AArch64 unary regression failed on the captured Moshi + activation before the fix and now passes all four GGML reference bits. SiLU is selected + by an explicit guard/transition, executes the reference NEON polynomial, and the old + runtime-indexed unary function table was removed. + implication: the parity fix adds no hidden behavior selection and also replaces a scalar + hot-path activation with four-lane SIMD. + +- timestamp: 2026-07-09T20:00:00-05:00 + observation: the release CPU runner now exactly matches CPU moshi.cpp for all 16 sampled + tokens in voice frame 0 and for every voice frame through frame 8 (144 consecutive audio + tokens). The first mismatch is frame 9, codebook 4: EMEL selects 655 while the reference + selects 855. + implication: the SiLU correction moves deterministic token parity from one codebook to + nine complete voice frames. Remaining sampled divergence is later and seed-sensitive, + rather than a gross model, RNG, or input-schedule mismatch. + +- timestamp: 2026-07-09T20:05:00-05:00 + observation: immediately before EMEL's frame-9/codebook-4 exponential draw, token 655 is + rank 5 with probability 0.0470813811 and token 855 is rank 6 with probability + 0.0437657684; the injected Park-Miller state is 1942131806 and deterministically selects + rank 5. + implication: the next comparison should test whether the CPU reference swaps these + adjacent candidates, as happened at the earlier frame-0 boundary. + +- timestamp: 2026-07-09T20:10:00-05:00 + observation: CPU moshi.cpp ranks 855 fifth and 655 sixth at voice frame 9/codebook 4; + EMEL ranks 655 fifth and 855 sixth. Both lanes begin the draw from Park-Miller state + 1942131806 and therefore select their respective fifth-ranked token. + implication: the remaining divergence is confirmed as accumulated adjacent-logit + ordering, not different RNG state, draw count, top-k size, or sampling algorithm. + +- timestamp: 2026-07-09T20:45:00-05:00 + observation: debugger-only captures from the public E2E actor dispatch show that the + frame-9/codebook-4 temporal `transformer_out` is already unequal in every f32 element + (maximum absolute difference 0.150205, mean absolute difference 0.016466, RMSE + 0.021238, correlation 0.999879). The following depformer input projection remains close + (maximum absolute difference 0.031275, correlation 0.999500). + implication: the first sampled-token mismatch does not originate in the sampler or the + depformer input projection. Its earliest currently proven operand is the temporal output + handed to depformer. + +- timestamp: 2026-07-09T20:47:00-05:00 + observation: frame-9/codebook-4 depformer layer-0 arrays remain closely correlated after + the unequal temporal operand: norm2/gating input correlation 0.999207, Q4_K gating + projection 0.999828, gated activation 0.999166, and FF update 0.998632. The respective + maximum absolute differences are 0.09743, 0.06839, 0.03532, and 0.01666. + implication: no new actor-level depformer regression is warranted. Layer 0 propagates an + upstream temporal difference rather than exposing a discrete new arithmetic failure. + +- timestamp: 2026-07-09T20:50:00-05:00 + observation: the maintained isolated 30-frame comparison feeds the same 240 public Mimi + tokens to both lanes exactly. EMEL/reference output RMS is 0.00213/0.10288, active-frame + ratio is 0.033/0.400, all-codebook token match is 0.2042, first-four match is 0.3833, + text match is 0.5667, and energy correlation is 0.4998. + implication: the remaining audible-output failure is not caused by WAV framing or Mimi + input tokens. The voice/prompt Moshi numeric path remains the active fault boundary. + +- timestamp: 2026-07-09T20:55:00-05:00 + observation: `tools/bench/speech/personaplex_emel_runner.cpp` is a maintained isolated + EMEL lane, but its prefill/live/flush sequencing, completion/error choices, lazy cache + allocation, and produced/decode routing are still implemented in procedural helpers, + lambdas, loops, and `if` branches. Its graph callback also performs synchronous logging + while the parent generator dispatch is still inside its RTC boundary. + implication: the file is suitable as a diagnostic benchmark adapter, not yet as the + requested architecture-compliant runtime entrypoint. Promotion requires a variant-named + SML session actor, preallocated injected cache/storage, and guard/transition-owned phase, + validation, completion, and failure choices; the CLI should remain a thin preload/write + adapter around that actor. + +- timestamp: 2026-07-09T22:20:00-05:00 + observation: commit `0e8737de` promotes PersonaPlex orchestration into a variant-named + SML session actor with injected temporal/depformer caches, storage, sampling policy, and + frame target. The maintained 125-frame CPU comparison produces both 10-second WAVs. The + 29 actual WAV frames match all 232 public Mimi input tokens exactly; output match is + 0.161 overall, 0.192 for the first four codebooks, and 0.608 for text. Audio RMS is + 0.03488/0.07828, active ratio is 0.168/0.480, and best log-energy correlation is 0.3603. + implication: the maintained architecture and same-WAV input contract are satisfied. The + only maintained report threshold still failing is first-four output-token match + 0.192 < 0.300, so numeric temporal-transformer isolation remains required. + +- timestamp: 2026-07-09T22:35:00-05:00 + observation: scheduled CPU-reference copies and debugger-only EMEL copies from the public + actor lane show frame-9 temporal layer 0 is bit-for-bit identical at norm1 (4,096 f32), + QKV projection (12,288), attention pre-output (4,096), attention residual (4,096), + norm2/gating input (4,096), gating projection (22,528), gated activation (11,264), FF + update (4,096), and final layer output (4,096). + implication: temporal layer 0, including its history-dependent attention result and both + Q4_K projections, is eliminated. A regression against any layer-0 operation would be + already passing and would not reproduce the remaining fault; isolation must continue at + layer 1 or later before production changes. + +- timestamp: 2026-07-09T22:42:00-05:00 + observation: frame-9 temporal outputs remain bit-exact through layer 25. Layer 26 is the + first unequal layer: its QKV projection is exact, but attention pre-output differs in + exactly 128 of 4,096 values, indices 1,152-1,279 (head 9). The head-local maximum is + 0.000115395. Subsequent layer-26 feed-forward work amplifies the difference to a + 0.00133740 maximum at the layer output and layer 31 reaches 0.0398528. + implication: the first maintained temporal divergence is isolated to layer-26 attention + head 9 rather than a layer-specific Q4_K projection, gating operation, or residual path. + +- timestamp: 2026-07-09T22:44:00-05:00 + observation: layer 26 uses the same causal RoPE/RMSNorm/SiLU block, tensor shapes, and + Q4_K projection types as neighboring layers; there is no cross-attention, layer scale, + weights-per-step schedule, or model-specific route. EMEL and reference BF16 score-dot + disassembly also use the same 16-element f32 multiply and sequential f64 accumulation. + implication: a hidden layer route, dtype dispatch, and attention-score reduction order + are eliminated; query rotation, cached K/V, or softmax remained the candidate boundary. + +- timestamp: 2026-07-09T22:46:00-05:00 + observation: all ten frame-9 layer-26/head-9 K and V cache rows are bit-exact BF16. The + post-RoPE query differs by one ULP in 23 of 128 f32 lanes, but only lane 44 crosses a + BF16 tie: EMEL `0x3f908000` rounds to `0x3f90`, while reference `0x3f908001` rounds to + `0x3f91`. Replacing that one query BF16 value makes every one of the ten raw score dots + bit-exact. Before substitution, raw scores differ by at most 0.0102539 and normalized + weights by at most 0.0000842214. + implication: RoPE is the earliest causal operand divergence. K/V state, dot accumulation, + masking, and softmax only propagate the changed BF16 query. + +- timestamp: 2026-07-09T22:48:00-05:00 + observation: AArch64 disassembly shows EMEL lowers + `real * cos - imag * sin` to `fnmul` + `fmadd` and the imaginary result to `fmul` + + `fmadd`. The reference builds four independent GGML multiply tensors before add/subtract, + forcing each product to round to f32 first. + implication: the arithmetic defect is contraction across a reference-mandated f32 round + point, not a different RoPE frequency, position, pairing, or trigonometric function. + +- timestamp: 2026-07-09T22:56:00-05:00 + observation: after routing split-layout timestep RoPE through explicit CPU kernel actor + transitions with separate f32 product round points, the maintained 30-frame comparison + matches 232/232 actual-WAV input tokens, 240/240 public output tokens, 120/120 first-four + tokens, and 30/30 text tokens. EMEL/reference RMS is 0.10287923/0.10287953, both active + ratios are 0.400, and log-energy correlation is 0.999999957 at zero lag. + implication: the isolated RoPE defect fully explains the previously failing public-token + report at this focused horizon. The unchanged 125-frame comparison is now the required + maintained end-to-end verification rather than another arithmetic search. + +- timestamp: 2026-07-09T23:02:00-05:00 + observation: the fresh maintained 125-frame comparison at + `build/personaplex_compare_organic_rope_fix_10s/personaplex_compare.json` passes every + unchanged threshold. Actual-WAV input is 232/232, public output is 1,000/1,000, + first-four output is 500/500, and text is 125/125. EMEL/reference RMS is + 0.078284165/0.078284263, active ratio is 0.480/0.480, and log-energy correlation is + 0.999999967 at zero lag. EMEL took 57.90 seconds versus 259.12 seconds for the pinned + one-thread CPU reference, a 4.475x reference/EMEL ratio. + implication: the same-WAV, fixed-seed, CPU-only PersonaPlex comparison is fully passing; + the earlier 0.192 first-four failure is eliminated without weakening any threshold. + +- timestamp: 2026-07-09T23:18:00-05:00 + observation: after rebuilding the maintained runner from the final visible guarded and + unchecked actor source, the unchanged 125-frame comparison at + `build/personaplex_compare_organic_rope_guarded_10s/personaplex_compare.json` reproduced + the exact prior WAV hashes and passed again: 232/232 actual-WAV input tokens, 1,000/1,000 + public output tokens, 500/500 first-four output tokens, and 125/125 text tokens. Audio + energy correlation is 0.999999967 at zero lag with equal 0.480 activity. EMEL took + 59.20 seconds and the one-thread CPU moshi.cpp reference took 298.05 seconds, so the + measured reference/EMEL ratio is 5.035x. + implication: the result is reproducible from the committed architecture rather than a + stale diagnostic binary, and both audible WAVs are retained with the final report. + +- timestamp: 2026-07-09T23:26:00-05:00 + observation: the changed-file gate passed both affected test shards, 96.5% changed-line + coverage, 58.2% changed-branch coverage, live GGML kernel parity, and cross-process + determinism. The aggregate command remained nonzero because a stale repository benchmark + dependency manifest forced a full-suite comparison that lacks the pre-existing + `sm_scheduler/idle_async` and `sm_scheduler/busy_worker_async` entries, and the global + lint snapshot has unrelated drift. After local formatting, neither task-owned file is in + the lint delta; no snapshot was updated. + implication: all implementation-specific lanes are green, while the remaining gate + failures are structural repository baselines outside this change. + +- timestamp: 2026-07-09T20:15:00-05:00 + observation: the corrected release EMEL lane generated a 10.000-second, mono 24 kHz s16 + WAV from the organic input in 58.90 seconds on one CPU thread. The matching CPU + moshi.cpp run took 314.356 seconds; EMEL is 5.34x faster for this end-to-end run. + implication: the native unpacked EMEL path now has both audible output and measured + single-thread throughput evidence against the same effective Q4_K model class. + +- timestamp: 2026-07-09T20:25:00-05:00 + observation: the final scoped gates passed 75 AArch64 tests (8,139 assertions), 90.2% + changed-line coverage, 58.4% changed-branch coverage, the + AArch64 benchmark lane, live GGML kernel parity, and cross-process determinism. The only + final command failure is the repository-wide pre-existing lint snapshot delta; task-owned + AArch64 guard/SM entries were removed from that delta and the snapshot was not updated. + implication: implementation-specific verification is green without weakening gates or + changing the user-controlled lint baseline. + ## Eliminated - hypothesis: the Moshi reference swaps the first two top-k indices before drawing exponentials. @@ -107,16 +374,27 @@ updated: 2026-07-09 ## Resolution -- root_cause: reference-sensitive sampling and numeric operand order differed at four - boundaries: raw-logit top-k, process-global RNG state, Q4_K block accumulation, and RMS - square widening. -- fix: materialize full-card f32 probabilities, use actor-owned Park-Miller state, model - sampling phases and seed/top-k choices as explicit guarded transitions, and preserve - GGML Q4_K/RMS arithmetic order. Runtime sampling parameters remain injected; model - positional/prompt/voice/delay policy remains GGUF-derived. -- verification: complete EMEL and CPU-only reference WAVs, successful `afplay` of both, - focused sampler/RNG/statechart/Q4_K/RMS/generation regressions, quantitative A/B - metrics, scoped benchmark, coverage, kernel parity, and determinism. The only global - gate exception is unrelated lint snapshot drift documented above. -- files_changed: kernel Q4_K/RMS numeric paths, Moshi executor sampling states/actions/ - guards/events/context/detail, focused tests, and this evidence log. +- root_cause: Moshi's split-layout timestep RoPE used the right frequency, position, + pairing, trigonometric values, and K/V state, but its action-level expression contracted + `real*cos - imag*sin` and `real*sin + imag*cos` into AArch64 FMA instructions. The pinned + GGML reference materializes four independent f32 multiply nodes before add/subtract. + At frame 9, temporal layer 26, head 9, query lane 44, that missing f32 round point changed + `0x3f908001` to `0x3f908000`, crossing BF16 `0x3f91` to `0x3f90`. One changed query lane + altered all ten scores and became the first sampled-token divergence. +- fix: add an explicit guarded split-timestep RoPE route to both CPU kernel actors, keep + each product's f32 round point, and route temporal query/key rotation through the + executor's injected kernel actor. Query rotate/copy and key rotate/copy are explicit, + statically bounded completion phases; success/error choices remain in guards and + transitions. Model period, tensor dimensions, position, caches, seed, temperatures, + top-k values, session storage, and frame target remain dependency-injected or event/model + supplied rather than process-global. +- verification: the captured public kernel actor regression matches both reference output + bits. The focused 30-frame comparison reaches exact public token/text parity and + 0.999999957 audio-energy correlation. The final rebuilt 125-frame CPU-only report passes with + exact 232/232 actual-WAV input tokens, 1,000/1,000 public output tokens, 500/500 + first-four tokens, 125/125 text tokens, 0.999999967 energy correlation, equal 0.480 + activity, and nearly identical RMS. It reproduces the prior output hashes from the final + actor source. Both lanes emit audible 10-second 24 kHz mono WAVs. +- files_changed: CPU kernel timestep-RoPE detail, AArch64/x86 guards/actions/transitions, + Moshi executor query/key RoPE phases, public kernel actor regression/helpers, and this + persistent evidence record. diff --git a/src/emel/kernel/aarch64/actions.hpp b/src/emel/kernel/aarch64/actions.hpp index 31b1f426..cfdf2994 100644 --- a/src/emel/kernel/aarch64/actions.hpp +++ b/src/emel/kernel/aarch64/actions.hpp @@ -9227,6 +9227,10 @@ using exec_scalar_op_rope_norm_t = ::emel::kernel::detail::exec_scalar_rope_op< using exec_scalar_op_rope_neox_t = ::emel::kernel::detail::exec_scalar_rope_op< ::emel::kernel::aarch64::event::dispatch_op_rope, context, detail::mark_done_op, true>; +using exec_scalar_op_rope_timestep_t = + ::emel::kernel::detail::exec_scalar_timestep_rope_op< + ::emel::kernel::aarch64::event::dispatch_op_rope, context, + detail::mark_done_op>; using exec_scalar_op_im2col_f32_t = ::emel::kernel::detail::exec_scalar_im2col_op< ::emel::kernel::aarch64::event::dispatch_op_im2col, context, @@ -9373,6 +9377,7 @@ inline constexpr exec_scalar_op_get_rows_q8_0_t exec_scalar_op_get_rows_q8_0{}; inline constexpr exec_scalar_op_get_rows_q4_k_t exec_scalar_op_get_rows_q4_k{}; inline constexpr exec_scalar_op_rope_norm_t exec_scalar_op_rope_norm{}; inline constexpr exec_scalar_op_rope_neox_t exec_scalar_op_rope_neox{}; +inline constexpr exec_scalar_op_rope_timestep_t exec_scalar_op_rope_timestep{}; inline constexpr exec_scalar_op_im2col_f32_t exec_scalar_op_im2col_f32{}; inline constexpr exec_scalar_op_im2col_f16_t exec_scalar_op_im2col_f16{}; inline constexpr exec_scalar_op_conv_transpose_1d_f32_t diff --git a/src/emel/kernel/aarch64/guards.hpp b/src/emel/kernel/aarch64/guards.hpp index 14bae548..c2571456 100644 --- a/src/emel/kernel/aarch64/guards.hpp +++ b/src/emel/kernel/aarch64/guards.hpp @@ -896,15 +896,39 @@ template struct get_rows_src_dtype_is { } }; -template struct rope_mode_is { +template struct rope_mode_is { bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_rope &ev, const action::context &) const noexcept { int32_t mode = 0; return ::emel::kernel::detail::read_op_param_i32( ev.request.op_params.data(), ev.request.op_params_size, 2u, mode) && - mode == (neox_mode ? ::emel::kernel::detail::rope_mode_neox - : ::emel::kernel::detail::rope_mode_norm); + mode == mode_value; + } +}; + +struct rope_timestep_layout_is { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_rope &ev, + const action::context &) const noexcept { + int32_t n_dims = 0; + return ::emel::kernel::detail::read_op_param_i32( + ev.request.op_params.data(), ev.request.op_params_size, 1u, + n_dims) && + n_dims > 0 && + static_cast(n_dims) == ev.request.src0.ne[0] && + ev.request.src0.data != ev.request.dst.data && + ::emel::kernel::detail::is_dense_contiguous(ev.request.src0) && + ::emel::kernel::detail::is_dense_contiguous(ev.request.src1) && + ::emel::kernel::detail::is_dense_contiguous(ev.request.dst); + } +}; + +struct rope_timestep_is { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_rope &ev, + const action::context &ctx) const noexcept { + return rope_mode_is<::emel::kernel::detail::rope_mode_timestep>{}(ev, + ctx) && + rope_timestep_layout_is{}(ev, ctx); } }; @@ -972,11 +996,23 @@ struct valid_op_mul_mat_f16 { using valid_op_rope_norm = ::emel::kernel::detail::valid_variant_guard< ::emel::kernel::aarch64::event::dispatch_op_rope, action::context, valid_op<::emel::kernel::aarch64::event::dispatch_op_rope>, - rope_mode_is>; + rope_mode_is<::emel::kernel::detail::rope_mode_norm>>; using valid_op_rope_neox = ::emel::kernel::detail::valid_variant_guard< ::emel::kernel::aarch64::event::dispatch_op_rope, action::context, valid_op<::emel::kernel::aarch64::event::dispatch_op_rope>, - rope_mode_is>; + rope_mode_is<::emel::kernel::detail::rope_mode_neox>>; +using valid_op_rope_timestep = ::emel::kernel::detail::valid_variant_guard< + ::emel::kernel::aarch64::event::dispatch_op_rope, action::context, + valid_op<::emel::kernel::aarch64::event::dispatch_op_rope>, + rope_timestep_is>; + +template <> struct invalid_op<::emel::kernel::aarch64::event::dispatch_op_rope> { + bool operator()(const ::emel::kernel::aarch64::event::dispatch_op_rope &ev, + const action::context &ctx) const noexcept { + return !valid_op_rope_norm{}(ev, ctx) && !valid_op_rope_neox{}(ev, ctx) && + !valid_op_rope_timestep{}(ev, ctx); + } +}; using valid_op_im2col_f32 = ::emel::kernel::detail::valid_variant_guard< ::emel::kernel::aarch64::event::dispatch_op_im2col, action::context, diff --git a/src/emel/kernel/aarch64/sm.hpp b/src/emel/kernel/aarch64/sm.hpp index 9d7965fb..865a9cc6 100644 --- a/src/emel/kernel/aarch64/sm.hpp +++ b/src/emel/kernel/aarch64/sm.hpp @@ -767,6 +767,11 @@ struct model { [ guard::valid_op_rope_neox{} ] / action::exec_scalar_op_rope_neox + , sml::state <= sml::state + + sml::event<::emel::kernel::aarch64::event::dispatch_op_rope> + [ guard::valid_op_rope_timestep{} ] + / action::exec_scalar_op_rope_timestep + , sml::state <= sml::state + sml::event<::emel::kernel::aarch64::event::dispatch_op_rope> [ guard::invalid_op_rope{} ] diff --git a/src/emel/kernel/detail.hpp b/src/emel/kernel/detail.hpp index c23fb7c5..c8a82643 100644 --- a/src/emel/kernel/detail.hpp +++ b/src/emel/kernel/detail.hpp @@ -4661,6 +4661,7 @@ struct rope_op_params { inline constexpr int32_t rope_mode_norm = 0; inline constexpr int32_t rope_mode_neox = 2; +inline constexpr int32_t rope_mode_timestep = 4; template inline bool read_rope_params(const request_type &request, @@ -4678,13 +4679,14 @@ inline bool read_rope_params(const request_type &request, template inline bool can_run_rope(const request_type &request) noexcept { rope_op_params params = {}; + const bool params_ok = read_rope_params(request, params); const bool same_shape = request.src0.ne[0] == request.dst.ne[0] && request.src0.ne[1] == request.dst.ne[1] && request.src0.ne[2] == request.dst.ne[2] && request.src0.ne[3] == request.dst.ne[3]; - return read_rope_params(request, params) && same_shape && - request.src0.data != nullptr && request.src1.data != nullptr && - request.src0.ne[0] > 0 && dtype_code(request.src0.type) == dtype_f32 && + return params_ok && same_shape && request.src0.data != nullptr && + request.src1.data != nullptr && request.src0.ne[0] > 0 && + dtype_code(request.src0.type) == dtype_f32 && dtype_code(request.dst.type) == dtype_f32 && dtype_code(request.src1.type) == dtype_i32 && request.src2.data == nullptr && @@ -4694,7 +4696,6 @@ inline bool can_run_rope(const request_type &request) noexcept { request.src1.ne[0] == request.src0.ne[2] && params.n_dims > 0 && (params.n_dims % 2) == 0 && static_cast(params.n_dims) <= request.src0.ne[0] && - (params.mode == rope_mode_norm || params.mode == rope_mode_neox) && params.ext_factor == 0.0f && std::isfinite(params.freq_base) && params.freq_base > 0.0f && std::isfinite(params.freq_scale) && params.freq_scale > 0.0f && std::isfinite(params.attn_factor); @@ -4759,6 +4760,61 @@ inline bool run_rope_as(const request_type &request) noexcept { return true; } +// Moshi's timestep embedding rotates adjacent projected pairs and writes the +// real and imaginary results into split halves. The reference graph computes +// each multiplication as its own f32 node, so volatile product temporaries are +// intentional round barriers that prevent contraction into FMA instructions. +template +inline void compute_timestep_rope(const request_type &request) noexcept { + float freq_base = 0.0f; + float freq_scale = 0.0f; + float attn_factor = 0.0f; + std::memcpy(&freq_base, + request.op_params.data() + 5u * sizeof(freq_base), + sizeof(freq_base)); + std::memcpy(&freq_scale, + request.op_params.data() + 6u * sizeof(freq_scale), + sizeof(freq_scale)); + std::memcpy(&attn_factor, + request.op_params.data() + 8u * sizeof(attn_factor), + sizeof(attn_factor)); + + const uint64_t cols = request.src0.ne[0]; + const uint64_t half_dims = cols / 2u; + const float neg_log_period = -std::log(freq_base); + const auto *src_base = static_cast(request.src0.data); + const auto *positions = static_cast(request.src1.data); + auto *dst_base = static_cast(request.dst.data); + + for (uint64_t i3 = 0; i3 < request.src0.ne[3]; ++i3) { + for (uint64_t i2 = 0; i2 < request.src0.ne[2]; ++i2) { + const float position = static_cast(positions[i2]); + for (uint64_t i1 = 0; i1 < request.src0.ne[1]; ++i1) { + const uint64_t row = + (i3 * request.src0.ne[2] + i2) * request.src0.ne[1] + i1; + const float *src_row = src_base + row * cols; + float *dst_row = dst_base + row * cols; + for (uint64_t pair = 0; pair < half_dims; ++pair) { + const float real = src_row[2u * pair]; + const float imaginary = src_row[2u * pair + 1u]; + const float frequency = + std::exp(neg_log_period * static_cast(pair) / + static_cast(half_dims)); + const float argument = position * frequency * freq_scale; + const float cosine = std::cos(argument) * attn_factor; + const float sine = std::sin(argument) * attn_factor; + volatile float real_cosine = real * cosine; + volatile float imaginary_sine = imaginary * sine; + volatile float real_sine = real * sine; + volatile float imaginary_cosine = imaginary * cosine; + dst_row[pair] = real_cosine - imaginary_sine; + dst_row[half_dims + pair] = real_sine + imaginary_cosine; + } + } + } + } +} + // ggml im2col op_params layout: i32 slots {s0, s1, p0, p1, d0, d1, is_2D}. struct im2col_op_params { int32_t s0 = 0; @@ -5049,6 +5105,15 @@ struct exec_scalar_rope_op { } }; +template +struct exec_scalar_timestep_rope_op { + void operator()(const dispatch_event_type &ev, + context_type &ctx) const noexcept { + compute_timestep_rope(ev.request); + mark_done_type{}(ev, ctx); + } +}; + template struct exec_scalar_im2col_op { diff --git a/src/emel/kernel/x86_64/actions.hpp b/src/emel/kernel/x86_64/actions.hpp index 61f59609..d45558f5 100644 --- a/src/emel/kernel/x86_64/actions.hpp +++ b/src/emel/kernel/x86_64/actions.hpp @@ -2627,6 +2627,10 @@ using exec_scalar_op_rope_norm_t = ::emel::kernel::detail::exec_scalar_rope_op< using exec_scalar_op_rope_neox_t = ::emel::kernel::detail::exec_scalar_rope_op< ::emel::kernel::x86_64::event::dispatch_op_rope, context, detail::mark_done_op, true>; +using exec_scalar_op_rope_timestep_t = + ::emel::kernel::detail::exec_scalar_timestep_rope_op< + ::emel::kernel::x86_64::event::dispatch_op_rope, context, + detail::mark_done_op>; using exec_scalar_op_im2col_f32_t = ::emel::kernel::detail::exec_scalar_im2col_op< ::emel::kernel::x86_64::event::dispatch_op_im2col, context, @@ -2723,6 +2727,7 @@ inline constexpr exec_scalar_op_get_rows_q8_0_t exec_scalar_op_get_rows_q8_0{}; inline constexpr exec_scalar_op_get_rows_q4_k_t exec_scalar_op_get_rows_q4_k{}; inline constexpr exec_scalar_op_rope_norm_t exec_scalar_op_rope_norm{}; inline constexpr exec_scalar_op_rope_neox_t exec_scalar_op_rope_neox{}; +inline constexpr exec_scalar_op_rope_timestep_t exec_scalar_op_rope_timestep{}; inline constexpr exec_scalar_op_im2col_f32_t exec_scalar_op_im2col_f32{}; inline constexpr exec_scalar_op_im2col_f16_t exec_scalar_op_im2col_f16{}; inline constexpr exec_scalar_op_conv_transpose_1d_f32_t diff --git a/src/emel/kernel/x86_64/guards.hpp b/src/emel/kernel/x86_64/guards.hpp index 2dbe3abc..cb3dac82 100644 --- a/src/emel/kernel/x86_64/guards.hpp +++ b/src/emel/kernel/x86_64/guards.hpp @@ -273,15 +273,39 @@ template struct get_rows_src_dtype_is { } }; -template struct rope_mode_is { +template struct rope_mode_is { bool operator()(const ::emel::kernel::x86_64::event::dispatch_op_rope &ev, const action::context &) const noexcept { int32_t mode = 0; return ::emel::kernel::detail::read_op_param_i32( ev.request.op_params.data(), ev.request.op_params_size, 2u, mode) && - mode == (neox_mode ? ::emel::kernel::detail::rope_mode_neox - : ::emel::kernel::detail::rope_mode_norm); + mode == mode_value; + } +}; + +struct rope_timestep_layout_is { + bool operator()(const ::emel::kernel::x86_64::event::dispatch_op_rope &ev, + const action::context &) const noexcept { + int32_t n_dims = 0; + return ::emel::kernel::detail::read_op_param_i32( + ev.request.op_params.data(), ev.request.op_params_size, 1u, + n_dims) && + n_dims > 0 && + static_cast(n_dims) == ev.request.src0.ne[0] && + ev.request.src0.data != ev.request.dst.data && + ::emel::kernel::detail::is_dense_contiguous(ev.request.src0) && + ::emel::kernel::detail::is_dense_contiguous(ev.request.src1) && + ::emel::kernel::detail::is_dense_contiguous(ev.request.dst); + } +}; + +struct rope_timestep_is { + bool operator()(const ::emel::kernel::x86_64::event::dispatch_op_rope &ev, + const action::context &ctx) const noexcept { + return rope_mode_is<::emel::kernel::detail::rope_mode_timestep>{}(ev, + ctx) && + rope_timestep_layout_is{}(ev, ctx); } }; @@ -338,11 +362,23 @@ using valid_op_mul_mat_f16 = ::emel::kernel::detail::valid_variant_guard< using valid_op_rope_norm = ::emel::kernel::detail::valid_variant_guard< ::emel::kernel::x86_64::event::dispatch_op_rope, action::context, valid_op<::emel::kernel::x86_64::event::dispatch_op_rope>, - rope_mode_is>; + rope_mode_is<::emel::kernel::detail::rope_mode_norm>>; using valid_op_rope_neox = ::emel::kernel::detail::valid_variant_guard< ::emel::kernel::x86_64::event::dispatch_op_rope, action::context, valid_op<::emel::kernel::x86_64::event::dispatch_op_rope>, - rope_mode_is>; + rope_mode_is<::emel::kernel::detail::rope_mode_neox>>; +using valid_op_rope_timestep = ::emel::kernel::detail::valid_variant_guard< + ::emel::kernel::x86_64::event::dispatch_op_rope, action::context, + valid_op<::emel::kernel::x86_64::event::dispatch_op_rope>, + rope_timestep_is>; + +template <> struct invalid_op<::emel::kernel::x86_64::event::dispatch_op_rope> { + bool operator()(const ::emel::kernel::x86_64::event::dispatch_op_rope &ev, + const action::context &ctx) const noexcept { + return !valid_op_rope_norm{}(ev, ctx) && !valid_op_rope_neox{}(ev, ctx) && + !valid_op_rope_timestep{}(ev, ctx); + } +}; using valid_op_im2col_f32 = ::emel::kernel::detail::valid_variant_guard< ::emel::kernel::x86_64::event::dispatch_op_im2col, action::context, diff --git a/src/emel/kernel/x86_64/sm.hpp b/src/emel/kernel/x86_64/sm.hpp index d4704b6b..0b4d635e 100644 --- a/src/emel/kernel/x86_64/sm.hpp +++ b/src/emel/kernel/x86_64/sm.hpp @@ -647,6 +647,11 @@ struct model { [ guard::valid_op_rope_neox{} ] / action::exec_scalar_op_rope_neox + , sml::state <= sml::state + + sml::event<::emel::kernel::x86_64::event::dispatch_op_rope> + [ guard::valid_op_rope_timestep{} ] + / action::exec_scalar_op_rope_timestep + , sml::state <= sml::state + sml::event<::emel::kernel::x86_64::event::dispatch_op_rope> [ guard::invalid_op_rope{} ] diff --git a/src/emel/speech/generator/moshi/executor/actions.hpp b/src/emel/speech/generator/moshi/executor/actions.hpp index 6b61b8df..d3485d6d 100644 --- a/src/emel/speech/generator/moshi/executor/actions.hpp +++ b/src/emel/speech/generator/moshi/executor/actions.hpp @@ -417,51 +417,97 @@ struct effect_run_temporal_layer_projection { } }; -struct effect_apply_temporal_layer_rope { +template struct effect_run_temporal_layer_rope { void operator()(const event::step_run &runtime_ev, - const context &ctx) const noexcept { + context &ctx) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; + const auto &snapshot = runtime_ev.request.memory_snapshot; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t head_dim = hidden_dim / lm.num_heads; - const int32_t half = head_dim / 2; runtime_ev.ctx.temporal_layer_rope_ok = false; - runtime_ev.ctx.temporal_logical_position = detail::current_logical_position( - runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id); - runtime_ev.ctx.temporal_physical_position = detail::physical_position( - runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, - runtime_ev.ctx.temporal_logical_position); - - const float neg_log_period = -std::log(static_cast(lm.max_period)); - const float position = - static_cast(runtime_ev.ctx.temporal_logical_position); - for (int32_t part = 0; part < 2; ++part) { - float *data = runtime_ev.ctx.qkv.data() + - static_cast(part) * static_cast(hidden_dim); - for (int32_t head = 0; head < lm.num_heads; ++head) { - float *head_data = - data + static_cast(head) * static_cast(head_dim); - for (int32_t index = 0; index < half; ++index) { - const float freq = - std::exp(neg_log_period * static_cast(index) / - static_cast(half)); - const float arg = position * freq; - const float rotr = std::cos(arg); - const float roti = std::sin(arg); - const float real = head_data[static_cast(2 * index)]; - const float imag = head_data[static_cast(2 * index + 1)]; - runtime_ev.ctx.rope[static_cast(index)] = - real * rotr - imag * roti; - runtime_ev.ctx.rope[static_cast(half + index)] = - real * roti + imag * rotr; - } - std::memcpy(head_data, runtime_ev.ctx.rope.data(), - static_cast(head_dim) * sizeof(float)); - } - } - runtime_ev.ctx.temporal_layer_rope_ok = true; + const size_t sequence = static_cast(runtime_ev.request.sequence_id); + runtime_ev.ctx.temporal_logical_position = + snapshot.sequence_length_values[sequence] - 1; + const size_t logical_block = static_cast( + runtime_ev.ctx.temporal_logical_position / snapshot.block_tokens); + const int32_t block_id = static_cast( + snapshot.sequence_kv_blocks[sequence][logical_block]); + runtime_ev.ctx.temporal_physical_position = + block_id * snapshot.block_tokens + + (runtime_ev.ctx.temporal_logical_position % snapshot.block_tokens); + + const uint64_t head_dim_u64 = static_cast(head_dim); + const uint64_t heads_u64 = static_cast(lm.num_heads); + const uint64_t hidden_dim_u64 = static_cast(hidden_dim); + const uint64_t element_bytes = sizeof(float); + const float *source = + runtime_ev.ctx.qkv.data() + projection_part * hidden_dim_u64; + emel::kernel::event::op_rope rope_ev{ + .src0 = + { + .data = source, + .type = emel::kernel::event::dtype::f32, + .ne = {head_dim_u64, heads_u64, 1u, 1u}, + .nb = {element_bytes, element_bytes * head_dim_u64, + element_bytes * hidden_dim_u64, + element_bytes * hidden_dim_u64}, + }, + .src1 = + { + .data = &runtime_ev.ctx.temporal_logical_position, + .type = emel::kernel::event::dtype::i32, + .ne = {1u, 1u, 1u, 1u}, + .nb = {sizeof(int32_t), sizeof(int32_t), sizeof(int32_t), + sizeof(int32_t)}, + }, + .dst = + { + .data = runtime_ev.ctx.rope.data(), + .type = emel::kernel::event::dtype::f32, + .ne = {head_dim_u64, heads_u64, 1u, 1u}, + .nb = {element_bytes, element_bytes * head_dim_u64, + element_bytes * hidden_dim_u64, + element_bytes * hidden_dim_u64}, + }, + }; + const int32_t rope_mode = emel::kernel::detail::rope_mode_timestep; + const float freq_base = static_cast(lm.max_period); + const float freq_scale = 1.0f; + const float ext_factor = 0.0f; + const float attn_factor = 1.0f; + std::memcpy(rope_ev.op_params.data() + 1u * sizeof(int32_t), &head_dim, + sizeof(head_dim)); + std::memcpy(rope_ev.op_params.data() + 2u * sizeof(int32_t), &rope_mode, + sizeof(rope_mode)); + std::memcpy(rope_ev.op_params.data() + 5u * sizeof(float), &freq_base, + sizeof(freq_base)); + std::memcpy(rope_ev.op_params.data() + 6u * sizeof(float), &freq_scale, + sizeof(freq_scale)); + std::memcpy(rope_ev.op_params.data() + 7u * sizeof(float), &ext_factor, + sizeof(ext_factor)); + std::memcpy(rope_ev.op_params.data() + 8u * sizeof(float), &attn_factor, + sizeof(attn_factor)); + rope_ev.op_params_size = 9u * sizeof(float); + runtime_ev.ctx.temporal_layer_rope_ok = ctx.kernel.process_event(rope_ev); + } +}; + +using effect_run_temporal_layer_query_rope = effect_run_temporal_layer_rope<0u>; +using effect_run_temporal_layer_key_rope = effect_run_temporal_layer_rope<1u>; + +template struct effect_copy_temporal_layer_rope { + void operator()(const event::step_run &runtime_ev, + const context &ctx) const noexcept { + const size_t hidden_dim = static_cast(ctx.session.hidden_dim); + std::memcpy(runtime_ev.ctx.qkv.data() + projection_part * hidden_dim, + runtime_ev.ctx.rope.data(), hidden_dim * sizeof(float)); } }; +using effect_copy_temporal_layer_query_rope = + effect_copy_temporal_layer_rope<0u>; +using effect_copy_temporal_layer_key_rope = effect_copy_temporal_layer_rope<1u>; + struct effect_write_temporal_layer_kv_cache { void operator()(const event::step_run &runtime_ev, const context &ctx) const noexcept { diff --git a/src/emel/speech/generator/moshi/executor/sm.hpp b/src/emel/speech/generator/moshi/executor/sm.hpp index a16638d1..2bee5d2d 100644 --- a/src/emel/speech/generator/moshi/executor/sm.hpp +++ b/src/emel/speech/generator/moshi/executor/sm.hpp @@ -52,6 +52,8 @@ struct state_temporal_layer_projection_run {}; struct state_temporal_layer_projection_result_decision {}; struct state_temporal_layer_rope {}; struct state_temporal_layer_rope_result_decision {}; +struct state_temporal_layer_key_rope {}; +struct state_temporal_layer_key_rope_result_decision {}; struct state_temporal_layer_cache_write {}; struct state_temporal_layer_cache_write_result_decision {}; struct state_temporal_layer_attention {}; @@ -361,19 +363,29 @@ struct model { / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion [ guard::guard_temporal_layer_rope_supported{} ] - / action::effect_apply_temporal_layer_rope{} + / action::effect_run_temporal_layer_query_rope{} , sml::state <= sml::state + sml::completion [ guard::guard_temporal_layer_rope_unsupported{} ] / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion [ guard::guard_temporal_layer_rope_succeeded{} ] + / action::effect_copy_temporal_layer_query_rope{} , sml::state <= sml::state + sml::completion [ guard::guard_temporal_layer_rope_failed{} ] / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state + , sml::state <= sml::state + + sml::completion + / action::effect_run_temporal_layer_key_rope{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_rope_succeeded{} ] + / action::effect_copy_temporal_layer_key_rope{} + , sml::state <= sml::state + + sml::completion [ guard::guard_temporal_layer_rope_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + sml::completion [ guard::guard_temporal_layer_cache_write_supported{} ] / action::effect_write_temporal_layer_kv_cache{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_temporal_layer_cache_write_unsupported{} ] / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state diff --git a/tests/kernel/lifecycle_tests.cpp b/tests/kernel/lifecycle_tests.cpp index 038bb314..05517641 100644 --- a/tests/kernel/lifecycle_tests.cpp +++ b/tests/kernel/lifecycle_tests.cpp @@ -44,6 +44,8 @@ using emel::kernel::test::make_quantized_src; using emel::kernel::test::make_q8_k_vector_src; using emel::kernel::test::make_smoke_op_event; using emel::kernel::test::make_src; +using emel::kernel::test::set_op_param_f32; +using emel::kernel::test::set_op_param_i32; using emel::kernel::test::to_fp16_storage; using emel::kernel::test::within_flash_online_f16_tolerance; @@ -82,6 +84,40 @@ void check_backend_op_paths(machine_type & machine, } // namespace +TEST_CASE("kernel timestep rope preserves ggml f32 round points") { + const auto check_machine = [](auto & machine) { + std::array src = {}; + std::array dst = {}; + src[88] = std::bit_cast(UINT32_C(0x3f91261c)); + src[89] = std::bit_cast(UINT32_C(0x3e9d87b5)); + int32_t position = 9; + + emel::kernel::event::op_rope rope_ev{ + .src0 = make_src(src.data(), dtype::f32, 128, 1, 1), + .src1 = make_src(&position, dtype::i32, 1), + .dst = make_dst(dst.data(), dtype::f32, 128, 1, 1), + }; + set_op_param_i32(rope_ev, 1u, 128); + set_op_param_i32(rope_ev, 2u, + emel::kernel::detail::rope_mode_timestep); + set_op_param_f32(rope_ev, 5u, 10000.0f); + set_op_param_f32(rope_ev, 6u, 1.0f); + set_op_param_f32(rope_ev, 7u, 0.0f); + set_op_param_f32(rope_ev, 8u, 1.0f); + + REQUIRE(machine.process_event(rope_ev)); + CHECK(std::bit_cast(dst[44]) == UINT32_C(0x3f908001)); + CHECK(std::bit_cast(dst[108]) == UINT32_C(0x3ea6cd3b)); + }; + + x86_64_sm x86_machine{ + emel::kernel::x86_64::action::context{false, {}, 0}}; + aarch64_sm arm_machine{ + emel::kernel::aarch64::action::context{false, {}, 0}}; + check_machine(x86_machine); + check_machine(arm_machine); +} + TEST_CASE("kernel_mul_mat_accepts_quantized_qk_weights") { using emel::kernel::detail::quant::QK_K; using emel::kernel::detail::quant::block_q2_k; diff --git a/tests/kernel/test_helpers.hpp b/tests/kernel/test_helpers.hpp index 5f030e1c..d2d6a6e9 100644 --- a/tests/kernel/test_helpers.hpp +++ b/tests/kernel/test_helpers.hpp @@ -26,6 +26,24 @@ inline bool within_flash_online_f16_tolerance(const float actual, return std::fabs(actual - expected) <= k_flash_online_f16_abs_tolerance; } +template +inline void set_op_param_i32(event_type &ev, const uint32_t slot, + const int32_t value) { + std::memcpy(ev.op_params.data() + slot * sizeof(int32_t), &value, + sizeof(value)); + ev.op_params_size = + std::max(ev.op_params_size, (slot + 1u) * sizeof(int32_t)); +} + +template +inline void set_op_param_f32(event_type &ev, const uint32_t slot, + const float value) { + std::memcpy(ev.op_params.data() + slot * sizeof(float), &value, + sizeof(value)); + ev.op_params_size = + std::max(ev.op_params_size, (slot + 1u) * sizeof(float)); +} + template inline void fill_default_nb(tensor_type & tensor) { const auto elem_size = diff --git a/tests/kernel/x86_64_tests.cpp b/tests/kernel/x86_64_tests.cpp index adf28609..20d34ccb 100644 --- a/tests/kernel/x86_64_tests.cpp +++ b/tests/kernel/x86_64_tests.cpp @@ -27,6 +27,8 @@ using emel::kernel::test::make_dst; using emel::kernel::test::make_flash_attn_ext_event; using emel::kernel::test::make_quantized_src; using emel::kernel::test::make_src; +using emel::kernel::test::set_op_param_f32; +using emel::kernel::test::set_op_param_i32; using emel::kernel::test::to_fp16_storage; using emel::kernel::test::within_flash_online_f16_tolerance; @@ -1852,27 +1854,6 @@ TEST_CASE("kernel_x86_64_simd_action_exec_marks_done") { emel::kernel::x86_64::error::none))); } -namespace { - -template -void set_op_param_i32(event_type &ev, const uint32_t slot, - const int32_t value) { - std::memcpy(ev.op_params.data() + slot * sizeof(int32_t), &value, - sizeof(value)); - ev.op_params_size = - std::max(ev.op_params_size, (slot + 1u) * sizeof(int32_t)); -} - -template -void set_op_param_f32(event_type &ev, const uint32_t slot, const float value) { - std::memcpy(ev.op_params.data() + slot * sizeof(float), &value, - sizeof(value)); - ev.op_params_size = - std::max(ev.op_params_size, (slot + 1u) * sizeof(float)); -} - -} // namespace - TEST_CASE("kernel_x86_64_get_rows_gathers_f32_and_q8_0_rows") { x86_64_sm machine{emel::kernel::x86_64::action::context{false, {}, 0}}; From 744adfa9ff3e2d9f39e0feb0a81965cff31dda26 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 00:34:23 -0500 Subject: [PATCH 06/61] feat: run PersonaPlex on packed Q4_K weights --- .../debug/moshi-personaplex-audio-parity.md | 55 ++++++++- docs/benchmarking.md | 19 +-- scripts/bench_personaplex_compare.sh | 16 ++- src/emel/kernel/aarch64/actions.hpp | 104 ++++++++-------- tests/kernel/aarch64_tests.cpp | 111 +++++++++++++++++- tools/bench/personaplex_compare.py | 18 +++ tools/bench/personaplex_compare_tests.cpp | 8 ++ 7 files changed, 272 insertions(+), 59 deletions(-) diff --git a/.planning/debug/moshi-personaplex-audio-parity.md b/.planning/debug/moshi-personaplex-audio-parity.md index 2325462f..e8e5f665 100644 --- a/.planning/debug/moshi-personaplex-audio-parity.md +++ b/.planning/debug/moshi-personaplex-audio-parity.md @@ -2,7 +2,7 @@ status: resolved trigger: "Make EMEL PersonaPlex Moshi generate real speech end to end from the same macOS say WAV input as moshi.cpp, with fixed-seed reference comparison showing closely matching audio/token behavior and an output WAV the user can hear. CPU only." created: 2026-07-09 -updated: 2026-07-09 +updated: 2026-07-10 --- # Moshi PersonaPlex Audio Parity @@ -359,6 +359,59 @@ updated: 2026-07-09 implication: implementation-specific verification is green without weakening gates or changing the user-controlled lint baseline. +- timestamp: 2026-07-10T00:10:00-05:00 + observation: the direct AArch64 Q4_K x8 BL8 operand path now preserves the native + per-block f32 scale/min accumulation order without reconstructing native rows or + materializing f32 weights. The 125-frame packed report at + `build/personaplex_compare_packed_parity_10s_manual/personaplex_compare.json` matches + 232/232 input tokens, 1,000/1,000 output tokens, 500/500 first-four tokens, and 125/125 + text tokens. Audio-energy correlation is 0.999999967 at zero lag. + implication: the packed artifact is a true native packed operand path with fixed-seed + behavior equivalent to the unpacked path, not a packed-to-native fallback. + +- timestamp: 2026-07-10T00:15:00-05:00 + observation: packed EMEL completed 125 frames in 50.671 seconds versus 57.99 seconds for + a fresh unpacked run and 261.648 seconds for one-thread CPU moshi.cpp. Packed and unpacked + EMEL WAVs are byte-identical; packed throughput is 2.467 frames/s, 1.144x the unpacked + throughput and 5.164x the reference throughput. + implication: direct packing improves end-to-end single-thread throughput by 14.4% while + preserving the audible/reference behavior. + +- timestamp: 2026-07-10T00:25:00-05:00 + observation: the PersonaPlex LM contains 4,313.8 MiB of Q4_K matrices, 176.8 MiB of + already-Q4_0 embedding tables, and only 1.06 MiB of F32 norms. The separate 331.2 MiB + Mimi artifact still contains 193.0 MiB of transformer/RVQ projection matrices. Its + maintained Q8_0 converter reduces those projections to 51.5 MiB and the complete Mimi + artifact to 189.7 MiB. + implication: Mimi projections are the meaningful non-Q4_K quantization target. LM norms + and the 0.4 MiB voice prompt cannot provide material size savings. + +- timestamp: 2026-07-10T00:30:00-05:00 + observation: the injected Q8_0 Mimi artifact completed the same packed-LM 125-frame run + in 42.74 seconds, a 1.186x speedup over the float-Mimi packed run. It retained 99.14% + actual-WAV input-code agreement, but autoregressive output-token agreement versus the + exact-parity EMEL baseline fell to 43.3%, text agreement to 70.4%, and waveform + correlation to 0.670. + implication: Q8_0 Mimi is a valid 141.5 MiB smaller/faster optional artifact, but it must + not replace the exact-reference artifact in parity claims. + +- timestamp: 2026-07-10T00:35:00-05:00 + observation: a late live-audio macOS sample profile placed 40.0% of top-of-stack samples + in the packed Q4_K kernel, 21.3% in Mimi transformer compute, 12.7% in temporal + attention, and roughly another 19% in Mimi convolution, im2col, f16 matmul, and tensor + access work. The 8-codebook PersonaPlex Mimi artifact also retains 24 unused 2 MiB + acoustic codebooks from the 32-codebook source. + implication: further speed work should optimize the packed LM kernel and Mimi compute; + further zero-drift size work should first prune the unused 48 MiB of Mimi codebooks. + +- timestamp: 2026-07-10T00:40:00-05:00 + observation: the final scoped gate passed the AArch64 benchmark, 98.0% changed-line and + 66.2% changed-branch coverage, live GGML kernel parity, cross-process determinism, and + the affected tests. The only aggregate failure is unrelated pre-existing global + clang-format snapshot drift, which was not updated. + implication: packed/Q8 changes and evidence are implementation-green without weakening + gates or changing user-owned snapshots. + ## Eliminated - hypothesis: the Moshi reference swaps the first two top-k indices before drawing exponentials. diff --git a/docs/benchmarking.md b/docs/benchmarking.md index b8bd6ebf..d7cd7f51 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -398,14 +398,17 @@ codebook count, and silence framing explicit and reproducible. the setup keeps t Mimi parity artifact separate from PersonaPlex's 8-public-codebook Mimi artifact. the report and both audible WAVs are written under `build/personaplex_compare/`. the report records -the input SHA256, exact public Mimi input-code match, sampled output-token match, text-token match, -lagged 80 ms energy correlation, activity ratio, non-silence, output hashes, and end-to-end wall -time. sampled output is compared as behavior rather than raw-waveform equality because a one-rank -floating-point difference can avalanche later fixed-seed draws even when the RNG state and sampling -policy agree. - -use `--frames`, `--seed`, `--threads`, `--output-dir`, `--build-only`, or `--run-only` to override -the injected run configuration. `--run-only` never fetches, converts, or rebuilds artifacts. +the input SHA256, EMEL/reference LM and Mimi paths and SHA256 values, exact public Mimi input-code +match, sampled output-token match, text-token match, lagged 80 ms energy correlation, activity +ratio, non-silence, output hashes, and end-to-end wall time. sampled output is compared as behavior +rather than raw-waveform equality because a one-rank floating-point difference can avalanche later +fixed-seed draws even when the RNG state and sampling policy agree. + +use `--emel-lm` and `--emel-mimi` (or `EMEL_PERSONAPLEX_EMEL_LM` and +`EMEL_PERSONAPLEX_EMEL_MIMI`) to inject packed or quantized EMEL artifacts without changing the +reference lane. use `--frames`, `--seed`, `--threads`, `--output-dir`, `--build-only`, or +`--run-only` to override the remaining injected run configuration. `--run-only` never fetches, +converts, or rebuilds artifacts. ## generation-specific local overrides diff --git a/scripts/bench_personaplex_compare.sh b/scripts/bench_personaplex_compare.sh index 042e1c8a..e35dbb3a 100755 --- a/scripts/bench_personaplex_compare.sh +++ b/scripts/bench_personaplex_compare.sh @@ -10,6 +10,8 @@ BUILD_DIR="${EMEL_PERSONAPLEX_COMPARE_BUILD_DIR:-$ROOT_DIR/build/personaplex_com OUTPUT_DIR="${EMEL_PERSONAPLEX_COMPARE_OUTPUT_DIR:-$ROOT_DIR/build/personaplex_compare}" ARTIFACT_DIR="${EMEL_MOSHI_REFERENCE_ARTIFACT_DIR:-$ROOT_DIR/build/moshi_reference}" AUDIO="" +EMEL_LM="${EMEL_PERSONAPLEX_EMEL_LM:-}" +EMEL_MIMI="${EMEL_PERSONAPLEX_EMEL_MIMI:-}" FRAMES=125 SEED=1234 THREADS=1 @@ -22,6 +24,10 @@ usage: scripts/bench_personaplex_compare.sh [options] --audio PATH 24 kHz mono s16 WAV; default uses macOS say for "Hey, I'm Gabe. How are you doing?" + --emel-lm PATH enriched EMEL LM artifact; defaults to the unpacked + model in the configured artifact directory + --emel-mimi PATH enriched EMEL Mimi artifact; defaults to the float + model in the configured artifact directory --frames N generated frames per lane (default: 125 / 10 seconds) --seed N fixed sampling seed (default: 1234) --threads N CPU threads in moshi.cpp reference lane (default: 1) @@ -34,6 +40,8 @@ USAGE while [[ $# -gt 0 ]]; do case "$1" in --audio) AUDIO="${2:-}"; shift 2 ;; + --emel-lm) EMEL_LM="${2:-}"; shift 2 ;; + --emel-mimi) EMEL_MIMI="${2:-}"; shift 2 ;; --frames) FRAMES="${2:-}"; shift 2 ;; --seed) SEED="${2:-}"; shift 2 ;; --threads) THREADS="${2:-}"; shift 2 ;; @@ -99,9 +107,13 @@ fi EMEL_RUNNER="$BUILD_DIR/personaplex_emel_runner" REFERENCE_DRIVER="$BUILD_DIR/moshi_reference_driver" -EMEL_MIMI="$ARTIFACT_DIR/mimi-e351c8d8-125-personaplex-emel.gguf" +if [[ -z "$EMEL_MIMI" ]]; then + EMEL_MIMI="$ARTIFACT_DIR/mimi-e351c8d8-125-personaplex-emel.gguf" +fi REFERENCE_MIMI="$ARTIFACT_DIR/mimi-e351c8d8-125.gguf" -EMEL_LM="$ARTIFACT_DIR/model-q4_k-emel.gguf" +if [[ -z "$EMEL_LM" ]]; then + EMEL_LM="$ARTIFACT_DIR/model-q4_k-emel.gguf" +fi REFERENCE_LM="$ARTIFACT_DIR/model-q4_k.gguf" EMEL_VOICE="$ARTIFACT_DIR/voices/NATF0-emel.gguf" REFERENCE_VOICE="$ARTIFACT_DIR/voices/NATF0.gguf" diff --git a/src/emel/kernel/aarch64/actions.hpp b/src/emel/kernel/aarch64/actions.hpp index cfdf2994..267d4f74 100644 --- a/src/emel/kernel/aarch64/actions.hpp +++ b/src/emel/kernel/aarch64/actions.hpp @@ -2789,6 +2789,17 @@ inline int32_t q4_k_min_sum_neon(const uint8_t *mins, } #endif +inline void +accumulate_q4_k_scaled_sums(const uint16_t lhs_d, const uint16_t lhs_dmin, + const float rhs_d, const int32_t min_sum, + const int32_t dot_sum, float &sum) noexcept { + const float d = ::emel::kernel::detail::quant::fp16_to_fp32(lhs_d) * rhs_d; + const float dmin = + ::emel::kernel::detail::quant::fp16_to_fp32(lhs_dmin) * rhs_d; + sum -= dmin * static_cast(min_sum); + sum += d * static_cast(dot_sum); +} + inline void accumulate_q4_k_q8_k_block_neon( const ::emel::kernel::detail::quant::block_q4_k &lhs, const ::emel::kernel::detail::quant::block_q8_k &rhs, float &sum) noexcept { @@ -2838,11 +2849,8 @@ inline void accumulate_q4_k_q8_k_block_neon( static_cast(scales[group * 2u + 1u]); } - const float d = ::emel::kernel::detail::quant::fp16_to_fp32(lhs.d) * rhs.d; - const float dmin = - ::emel::kernel::detail::quant::fp16_to_fp32(lhs.dmin) * rhs.d; - sum -= dmin * static_cast(min_sum); - sum += d * static_cast(low_sum + high_sum); + accumulate_q4_k_scaled_sums(lhs.d, lhs.dmin, rhs.d, min_sum, + low_sum + high_sum, sum); #endif } @@ -3102,32 +3110,25 @@ inline void dot_q4_k_x8_q8_k_group_bl8_neon( (void)block_count; std::fill(out, out + ::emel::kernel::detail::quant::Q4_K_X8_ROWS, 0.0f); #else + // Keep weights in their x8 interleaved representation for the integer dot + // work. Apply each block's float scale/min terms row-wise in the same order + // as the native Q4_K kernel so fixed-seed behavior remains bit-exact. constexpr uint64_t col_pairs = ::emel::kernel::detail::quant::Q4_K_X8_ROWS / 2u; - std::array - acc_f32 = {}; + std::array sums = {}; const uint8x16_t m4b = vdupq_n_u8(0x0fu); - for (auto &acc : acc_f32) { - acc = vdupq_n_f32(0.0f); - } for (uint64_t block = 0; block < block_count; ++block) { const auto &q4_block = lhs[block]; const auto &q8_block = rhs[block]; - const float32x4_t q4_d_0 = vcvt_f32_f16( - vld1_f16(reinterpret_cast(q4_block.d.data()))); - const float32x4_t q4_d_1 = vcvt_f32_f16( - vld1_f16(reinterpret_cast(q4_block.d.data() + 4u))); - const float32x4_t q8_d = vdupq_n_f32(q8_block.d); - const float32x4_t sb_scale_0 = vmulq_f32(q4_d_0, q8_d); - const float32x4_t sb_scale_1 = vmulq_f32(q4_d_1, q8_d); - const float32x4_t q4_dmin_0 = vcvt_f32_f16( - vld1_f16(reinterpret_cast(q4_block.dmin.data()))); - const float32x4_t q4_dmin_1 = vcvt_f32_f16( - vld1_f16(reinterpret_cast(q4_block.dmin.data() + 4u))); - const float32x4_t sb_min_0 = vmulq_f32(q4_dmin_0, q8_d); - const float32x4_t sb_min_1 = vmulq_f32(q4_dmin_1, q8_d); - + std::array low_acc = { + vdupq_n_s32(0), + vdupq_n_s32(0), + }; + std::array high_acc = { + vdupq_n_s32(0), + vdupq_n_s32(0), + }; std::array bias_acc = { vdupq_n_s32(0), vdupq_n_s32(0), @@ -3197,25 +3198,18 @@ inline void dot_q4_k_x8_q8_k_group_bl8_neon( q8_qs[7]); } - for (uint64_t i = 0, pair = 0; pair < col_pairs; i += 1u, pair += 2u) { - const int16x4_t group_scales_lo = pair == 0u - ? vget_low_s16(q4sb_scales[0]) - : vget_high_s16(q4sb_scales[0]); - const int16x4_t group_scales_hi = pair == 0u - ? vget_low_s16(q4sb_scales[1]) - : vget_high_s16(q4sb_scales[1]); - const float32x4_t sb_scale = pair == 0u ? sb_scale_0 : sb_scale_1; - - const float32x4_t sumf_0 = vcvtq_f32_s32( - vmulq_s32(vmovl_s16(group_scales_lo), - vpaddq_s32(acc_lo[pair], acc_lo[pair + 1u]))); - acc_f32[i] = vfmaq_f32(acc_f32[i], sb_scale, sumf_0); - - const float32x4_t sumf_1 = vcvtq_f32_s32( - vmulq_s32(vmovl_s16(group_scales_hi), - vpaddq_s32(acc_hi[pair], acc_hi[pair + 1u]))); - acc_f32[i] = vfmaq_f32(acc_f32[i], sb_scale, sumf_1); - } + low_acc[0] = vaddq_s32(low_acc[0], + vmulq_s32(vmovl_s16(vget_low_s16(q4sb_scales[0])), + vpaddq_s32(acc_lo[0], acc_lo[1]))); + high_acc[0] = vaddq_s32(high_acc[0], + vmulq_s32(vmovl_s16(vget_low_s16(q4sb_scales[1])), + vpaddq_s32(acc_hi[0], acc_hi[1]))); + low_acc[1] = vaddq_s32(low_acc[1], + vmulq_s32(vmovl_s16(vget_high_s16(q4sb_scales[0])), + vpaddq_s32(acc_lo[2], acc_lo[3]))); + high_acc[1] = vaddq_s32( + high_acc[1], vmulq_s32(vmovl_s16(vget_high_s16(q4sb_scales[1])), + vpaddq_s32(acc_hi[2], acc_hi[3]))); const int16x4_t bsums_vec_lo = vdup_n_s16(bsums_array[2u * sb + 0u]); const int16x4_t bsums_vec_hi = vdup_n_s16(bsums_array[2u * sb + 1u]); @@ -3229,12 +3223,28 @@ inline void dot_q4_k_x8_q8_k_group_bl8_neon( vmlal_s16(bias_acc[1], bsums_vec_hi, vget_high_s16(q4sb_mins[1])); } - acc_f32[0] = vmlsq_f32(acc_f32[0], vcvtq_f32_s32(bias_acc[0]), sb_min_0); - acc_f32[1] = vmlsq_f32(acc_f32[1], vcvtq_f32_s32(bias_acc[1]), sb_min_1); + alignas(16) std::array + low_sums = {}; + alignas(16) std::array + high_sums = {}; + alignas(16) std::array + min_sums = {}; + vst1q_s32(low_sums.data(), low_acc[0]); + vst1q_s32(low_sums.data() + 4u, low_acc[1]); + vst1q_s32(high_sums.data(), high_acc[0]); + vst1q_s32(high_sums.data() + 4u, high_acc[1]); + vst1q_s32(min_sums.data(), bias_acc[0]); + vst1q_s32(min_sums.data() + 4u, bias_acc[1]); + + for (uint64_t row = 0; row < ::emel::kernel::detail::quant::Q4_K_X8_ROWS; + ++row) { + accumulate_q4_k_scaled_sums(q4_block.d[row], q4_block.dmin[row], + q8_block.d, min_sums[row], + low_sums[row] + high_sums[row], sums[row]); + } } - vst1q_f32(out, acc_f32[0]); - vst1q_f32(out + 4u, acc_f32[1]); + std::copy(sums.begin(), sums.end(), out); #endif } diff --git a/tests/kernel/aarch64_tests.cpp b/tests/kernel/aarch64_tests.cpp index 7cd1b0ac..9972bb48 100644 --- a/tests/kernel/aarch64_tests.cpp +++ b/tests/kernel/aarch64_tests.cpp @@ -2674,6 +2674,7 @@ TEST_CASE( std::array native_out = {}; std::array packed_bl4_out = {}; + std::array packed_bl4_f32_out = {}; std::array packed_bl8_out = {}; std::array packed_bl8_f32_out = {}; const emel::kernel::event::op_mul_mat native_ev{ @@ -2694,6 +2695,13 @@ TEST_CASE( .src1 = make_q8_k_vector_src(q8_input.data(), QK_K), .dst = make_dst(packed_bl8_out.data(), dtype::f32, 1u, Q4_K_X8_ROWS), }; + const emel::kernel::event::op_mul_mat packed_bl4_f32_ev{ + .src0 = make_packed_q4_k_x8_bl4_src(packed_bl4_storage.data(), QK_K, + Q4_K_X8_ROWS), + .src1 = make_src(input.data(), dtype::f32, 1u, QK_K), + .dst = + make_dst(packed_bl4_f32_out.data(), dtype::f32, 1u, Q4_K_X8_ROWS), + }; const emel::kernel::event::op_mul_mat packed_bl8_f32_ev{ .src0 = make_packed_q4_k_x8_bl8_src(packed_bl8_storage.data(), QK_K, Q4_K_X8_ROWS), @@ -2703,6 +2711,15 @@ TEST_CASE( }; float argmax_score = 0.0f; int32_t argmax_index = -1; + float bl4_argmax_score = 0.0f; + int32_t bl4_argmax_index = -1; + const emel::kernel::event::op_mul_mat_argmax packed_bl4_f32_argmax_ev{ + .src0 = make_packed_q4_k_x8_bl4_src(packed_bl4_storage.data(), QK_K, + Q4_K_X8_ROWS), + .src1 = make_src(input.data(), dtype::f32, 1u, QK_K), + .dst = make_dst(&bl4_argmax_score, dtype::f32, 1u, 1u), + .index_out = &bl4_argmax_index, + }; const emel::kernel::event::op_mul_mat_argmax packed_bl8_f32_argmax_ev{ .src0 = make_packed_q4_k_x8_bl8_src(packed_bl8_storage.data(), QK_K, Q4_K_X8_ROWS), @@ -2713,11 +2730,16 @@ TEST_CASE( aarch64_sm native_machine{}; aarch64_sm packed_bl4_machine{}; + aarch64_sm packed_bl4_f32_machine{}; + aarch64_sm packed_bl4_f32_argmax_machine{}; aarch64_sm packed_bl8_machine{}; aarch64_sm packed_bl8_f32_machine{}; aarch64_sm packed_bl8_f32_argmax_machine{}; CHECK(native_machine.process_event(native_ev)); CHECK(packed_bl4_machine.process_event(packed_bl4_ev)); + CHECK(packed_bl4_f32_machine.process_event(packed_bl4_f32_ev)); + CHECK(packed_bl4_f32_argmax_machine.process_event( + packed_bl4_f32_argmax_ev)); CHECK(packed_bl8_machine.process_event(packed_bl8_ev)); CHECK(packed_bl8_f32_machine.process_event(packed_bl8_f32_ev)); CHECK(packed_bl8_f32_argmax_machine.process_event( @@ -2735,11 +2757,20 @@ TEST_CASE( for (size_t row = 0; row < native_out.size(); ++row) { CHECK(packed_bl4_out[row] == doctest::Approx(native_out[row]).epsilon(1.0e-5f)); + CHECK(packed_bl4_f32_out[row] == + doctest::Approx(native_out[row]).epsilon(1.0e-5f)); CHECK(packed_bl8_out[row] == doctest::Approx(native_out[row]).epsilon(1.0e-5f)); CHECK(packed_bl8_f32_out[row] == doctest::Approx(native_out[row]).epsilon(1.0e-5f)); - } + CHECK(std::bit_cast(packed_bl8_out[row]) == + std::bit_cast(native_out[row])); + CHECK(std::bit_cast(packed_bl8_f32_out[row]) == + std::bit_cast(native_out[row])); + } + CHECK(bl4_argmax_index == expected_argmax_index); + CHECK(bl4_argmax_score == + doctest::Approx(expected_argmax_score).epsilon(1.0e-5f)); CHECK(argmax_index == expected_argmax_index); CHECK(argmax_score == doctest::Approx(expected_argmax_score).epsilon(1.0e-5f)); @@ -2749,6 +2780,17 @@ TEST_CASE( CHECK(packed_bl4_machine.optimized_q4_vector_packed_q8_rhs_dispatch_count() == 1u); CHECK(packed_bl4_machine.shared_q4_dispatch_count() == 0u); + CHECK(packed_bl4_f32_machine.optimized_q4_dispatch_count() == 1u); + CHECK(packed_bl4_f32_machine.optimized_q4_vector_dispatch_count() == 1u); + CHECK(packed_bl4_f32_machine.optimized_q4_vector_packed_dispatch_count() == + 1u); + CHECK(packed_bl4_f32_machine.shared_q4_dispatch_count() == 0u); + CHECK(packed_bl4_f32_argmax_machine.optimized_q4_dispatch_count() == 1u); + CHECK(packed_bl4_f32_argmax_machine.optimized_q4_vector_dispatch_count() == + 1u); + CHECK(packed_bl4_f32_argmax_machine + .optimized_q4_vector_packed_dispatch_count() == 1u); + CHECK(packed_bl4_f32_argmax_machine.shared_q4_dispatch_count() == 0u); CHECK(packed_bl8_machine.optimized_q4_dispatch_count() == 1u); CHECK(packed_bl8_machine.optimized_q4_vector_dispatch_count() == 1u); CHECK(packed_bl8_machine.optimized_q4_vector_packed_dispatch_count() == 1u); @@ -2771,6 +2813,73 @@ TEST_CASE( #endif } +TEST_CASE("kernel_aarch64_q4_packed_bl8_preserves_native_block_order_bits") { +#if !(defined(__aarch64__) && defined(__ARM_NEON) && \ + defined(__ARM_FEATURE_DOTPROD)) + CHECK(true); +#else + using emel::kernel::detail::quant::block_q4_k; + using emel::kernel::detail::quant::block_q4_kx8; + using emel::kernel::detail::quant::Q4_K_X8_ROWS; + using emel::kernel::detail::quant::QK_K; + + constexpr uint64_t block_count = 4u; + constexpr uint64_t cols = block_count * QK_K; + std::array native_rows = {}; + for (size_t row = 0; row < Q4_K_X8_ROWS; ++row) { + for (size_t block = 0; block < block_count; ++block) { + auto &value = native_rows[row * block_count + block]; + value.d = static_cast(0x3000u + row * 31u + block * 7u); + value.dmin = static_cast(0x2800u + row * 19u + block * 11u); + for (size_t index = 0; index < value.scales.size(); ++index) { + value.scales[index] = static_cast( + (row * 37u + block * 53u + index * 17u + 9u) & 0xffu); + } + for (size_t index = 0; index < value.qs.size(); ++index) { + value.qs[index] = static_cast( + (row * 29u + block * 43u + index * 13u + 5u) & 0xffu); + } + } + } + + const std::array input = [] { + std::array values = {}; + for (size_t index = 0; index < values.size(); ++index) { + const int32_t centered = static_cast(index % 61u) - 30; + values[index] = static_cast(centered) * 0.03125f; + } + return values; + }(); + + std::array packed = {}; + REQUIRE(emel::kernel::detail::quant::pack_q4_k_rows_x8_bl8( + native_rows.data(), Q4_K_X8_ROWS, cols, packed.data())); + + std::array native_out = {}; + std::array packed_out = {}; + const emel::kernel::event::op_mul_mat native_ev{ + .src0 = make_quantized_src(native_rows.data(), dtype::q4_k, cols, + Q4_K_X8_ROWS), + .src1 = make_src(input.data(), dtype::f32, 1u, cols), + .dst = make_dst(native_out.data(), dtype::f32, 1u, Q4_K_X8_ROWS), + }; + const emel::kernel::event::op_mul_mat packed_ev{ + .src0 = make_packed_q4_k_x8_bl8_src(packed.data(), cols, Q4_K_X8_ROWS), + .src1 = make_src(input.data(), dtype::f32, 1u, cols), + .dst = make_dst(packed_out.data(), dtype::f32, 1u, Q4_K_X8_ROWS), + }; + + aarch64_sm native_machine{}; + aarch64_sm packed_machine{}; + REQUIRE(native_machine.process_event(native_ev)); + REQUIRE(packed_machine.process_event(packed_ev)); + for (size_t row = 0; row < native_out.size(); ++row) { + CHECK(std::bit_cast(packed_out[row]) == + std::bit_cast(native_out[row])); + } +#endif +} + TEST_CASE("kernel_aarch64_raw_quantized_prepared_rhs_routes_are_explicit_and_" "numeric_match") { #if !(defined(__aarch64__) && defined(__ARM_NEON) && \ diff --git a/tools/bench/personaplex_compare.py b/tools/bench/personaplex_compare.py index a24c5e29..491ec76c 100755 --- a/tools/bench/personaplex_compare.py +++ b/tools/bench/personaplex_compare.py @@ -320,6 +320,24 @@ def main() -> int: "prompt_text_token": prompt_text_token, "frame_samples": frame_samples, }, + "models": { + "emel_mimi": { + "path": str(Path(args.emel_mimi).resolve()), + "sha256": sha256(Path(args.emel_mimi)), + }, + "reference_mimi": { + "path": str(Path(args.reference_mimi).resolve()), + "sha256": sha256(Path(args.reference_mimi)), + }, + "emel_lm": { + "path": str(Path(args.emel_lm).resolve()), + "sha256": sha256(Path(args.emel_lm)), + }, + "reference_lm": { + "path": str(Path(args.reference_lm).resolve()), + "sha256": sha256(Path(args.reference_lm)), + }, + }, "input": { "path": str(Path(args.audio).resolve()), "sha256": sha256(Path(args.audio)), diff --git a/tools/bench/personaplex_compare_tests.cpp b/tools/bench/personaplex_compare_tests.cpp index 2cd0ecf4..c6b9f9fd 100644 --- a/tools/bench/personaplex_compare_tests.cpp +++ b/tools/bench/personaplex_compare_tests.cpp @@ -107,6 +107,10 @@ TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { CHECK(wrapper_source.find("--audio \"$AUDIO\"") != std::string::npos); CHECK(wrapper_source.find("--inference-config \"$INFERENCE_CONFIG\"") != std::string::npos); + CHECK(wrapper_source.find("--emel-lm PATH") != std::string::npos); + CHECK(wrapper_source.find("--emel-lm) EMEL_LM=") != std::string::npos); + CHECK(wrapper_source.find("--emel-mimi PATH") != std::string::npos); + CHECK(wrapper_source.find("--emel-mimi) EMEL_MIMI=") != std::string::npos); CHECK(wrapper_source.find("--data-format=LEI16@24000") != std::string::npos); CHECK(wrapper_source.find("mimi-e351c8d8-125-personaplex-emel.gguf") != std::string::npos); @@ -120,6 +124,10 @@ TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { CHECK(emel_source.find("sampling_seed = 1234") == std::string::npos); CHECK(emel_source.find(".max_blocks = 256") == std::string::npos); CHECK(compare_source.find("\"--n-q\", \"8\"") == std::string::npos); + CHECK(compare_source.find("\"emel_lm\": {") != std::string::npos); + CHECK(compare_source.find("\"reference_lm\": {") != std::string::npos); + CHECK(compare_source.find("\"emel_mimi\": {") != std::string::npos); + CHECK(compare_source.find("\"reference_mimi\": {") != std::string::npos); CHECK(setup_source.find("--inference-config \"$MOSHI_INFERENCE_CONFIG\"") != std::string::npos); CHECK(converter_source.find("--inference-config") != std::string::npos); From 060d96cf3dc99bd944aa97ccc1da699b2b88e570 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 01:41:02 -0500 Subject: [PATCH 07/61] feat: add streaming memory actor --- .planning/architecture/memory_streaming.md | 80 ++++++ .../architecture/mermaid/memory_streaming.mmd | 35 +++ CMakeLists.txt | 1 + README.md | 3 +- src/emel/machines.hpp | 6 +- src/emel/memory/streaming/actions.hpp | 117 +++++++++ src/emel/memory/streaming/context.hpp | 30 +++ src/emel/memory/streaming/errors.hpp | 16 ++ src/emel/memory/streaming/events.hpp | 48 ++++ src/emel/memory/streaming/guards.hpp | 76 ++++++ src/emel/memory/streaming/sm.hpp | 192 +++++++++++++++ tests/memory/streaming/lifecycle_tests.cpp | 232 ++++++++++++++++++ 12 files changed, 833 insertions(+), 3 deletions(-) create mode 100644 .planning/architecture/memory_streaming.md create mode 100644 .planning/architecture/mermaid/memory_streaming.mmd create mode 100644 src/emel/memory/streaming/actions.hpp create mode 100644 src/emel/memory/streaming/context.hpp create mode 100644 src/emel/memory/streaming/errors.hpp create mode 100644 src/emel/memory/streaming/events.hpp create mode 100644 src/emel/memory/streaming/guards.hpp create mode 100644 src/emel/memory/streaming/sm.hpp create mode 100644 tests/memory/streaming/lifecycle_tests.cpp diff --git a/.planning/architecture/memory_streaming.md b/.planning/architecture/memory_streaming.md new file mode 100644 index 00000000..9da98108 --- /dev/null +++ b/.planning/architecture/memory_streaming.md @@ -0,0 +1,80 @@ +# memory_streaming + +Source: [`emel/memory/streaming/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) + +## Mermaid + +```mermaid +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_empty : initialize [guard_configuration_valid_] / effect_initialize_ + state_uninitialized --> state_uninitialized : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_empty --> state_empty : initialize [always] / already_initialized__ + state_filling --> state_filling : initialize [always] / already_initialized__ + state_full --> state_full : initialize [always] / already_initialized__ + state_errored --> state_empty : initialize [guard_configuration_valid_] / effect_initialize_ + state_errored --> state_errored : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_empty --> state_full : advance [guard_capacity_one_] / wrap__ + state_empty --> state_filling : advance [guard_capacity_many_] / advance__ + state_filling --> state_filling : advance [guard_filling_remains_partial_] / advance__ + state_filling --> state_full : advance [guard_filling_becomes_full_] / wrap__ + state_full --> state_full : advance [guard_full_position_available_before_wrap_] / advance__ + state_full --> state_full : advance [guard_full_position_available_at_wrap_] / wrap__ + state_full --> state_full : advance [guard_full_position_overflow_] / position_overflow__ + state_full --> state_full : advance [guard_full_cursor_invalid_] / internal_error__ + state_empty --> state_empty : reset [always] / effect_reset_ + state_filling --> state_empty : reset [always] / effect_reset_ + state_full --> state_empty : reset [always] / effect_reset_ + state_empty --> state_empty : capture_view [always] / empty__ + state_filling --> state_filling : capture_view [always] / filling__ + state_full --> state_full : capture_view [always] / full__ + state_uninitialized --> state_uninitialized : advance [always] / uninitialized__ + state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ + state_uninitialized --> state_uninitialized : capture_view [always] / uninitialized__ + state_errored --> state_errored : advance [always] / internal_error__ + state_errored --> state_errored : reset [always] / internal_error__ + state_errored --> state_errored : capture_view [always] / internal_error__ + state_uninitialized --> state_errored : _ [always] / effect_unexpected_ + state_empty --> state_errored : _ [always] / effect_unexpected_ + state_filling --> state_errored : _ [always] / effect_unexpected_ + state_full --> state_errored : _ [always] / effect_unexpected_ + state_errored --> state_errored : _ [always] / effect_unexpected_ +``` + +## Transitions + +| Source | Event | Guard | Action | Target | +| --- | --- | --- | --- | --- | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_configuration_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_configuration_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`invalid_configuration>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_configuration_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_configuration_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`invalid_configuration>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_capacity_one>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`wrap>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_capacity_many>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_filling_remains_partial>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_filling_becomes_full>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`wrap>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_full_position_available_before_wrap>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_full_position_available_at_wrap>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`wrap>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_full_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`guard_full_cursor_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`capture_view`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`empty>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`capture_view`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`filling>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`capture_view`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`full>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`capture_view`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`capture_view`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_empty`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_filling`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/memory/streaming/sm.hpp) | diff --git a/.planning/architecture/mermaid/memory_streaming.mmd b/.planning/architecture/mermaid/memory_streaming.mmd new file mode 100644 index 00000000..8e5b4428 --- /dev/null +++ b/.planning/architecture/mermaid/memory_streaming.mmd @@ -0,0 +1,35 @@ +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_empty : initialize [guard_configuration_valid_] / effect_initialize_ + state_uninitialized --> state_uninitialized : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_empty --> state_empty : initialize [always] / already_initialized__ + state_filling --> state_filling : initialize [always] / already_initialized__ + state_full --> state_full : initialize [always] / already_initialized__ + state_errored --> state_empty : initialize [guard_configuration_valid_] / effect_initialize_ + state_errored --> state_errored : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_empty --> state_full : advance [guard_capacity_one_] / wrap__ + state_empty --> state_filling : advance [guard_capacity_many_] / advance__ + state_filling --> state_filling : advance [guard_filling_remains_partial_] / advance__ + state_filling --> state_full : advance [guard_filling_becomes_full_] / wrap__ + state_full --> state_full : advance [guard_full_position_available_before_wrap_] / advance__ + state_full --> state_full : advance [guard_full_position_available_at_wrap_] / wrap__ + state_full --> state_full : advance [guard_full_position_overflow_] / position_overflow__ + state_full --> state_full : advance [guard_full_cursor_invalid_] / internal_error__ + state_empty --> state_empty : reset [always] / effect_reset_ + state_filling --> state_empty : reset [always] / effect_reset_ + state_full --> state_empty : reset [always] / effect_reset_ + state_empty --> state_empty : capture_view [always] / empty__ + state_filling --> state_filling : capture_view [always] / filling__ + state_full --> state_full : capture_view [always] / full__ + state_uninitialized --> state_uninitialized : advance [always] / uninitialized__ + state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ + state_uninitialized --> state_uninitialized : capture_view [always] / uninitialized__ + state_errored --> state_errored : advance [always] / internal_error__ + state_errored --> state_errored : reset [always] / internal_error__ + state_errored --> state_errored : capture_view [always] / internal_error__ + state_uninitialized --> state_errored : _ [always] / effect_unexpected_ + state_empty --> state_errored : _ [always] / effect_unexpected_ + state_filling --> state_errored : _ [always] / effect_unexpected_ + state_full --> state_errored : _ [always] / effect_unexpected_ + state_errored --> state_errored : _ [always] / effect_unexpected_ diff --git a/CMakeLists.txt b/CMakeLists.txt index 93753f0d..66f27f7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,6 +235,7 @@ if(EMEL_ENABLE_TESTS) tests/memory/kv/lifecycle_tests.cpp tests/memory/recurrent/lifecycle_tests.cpp tests/memory/hybrid/lifecycle_tests.cpp + tests/memory/streaming/lifecycle_tests.cpp tests/graph/tensor/lifecycle_tests.cpp tests/model/tensor/lifecycle_tests.cpp tests/model/tensor/window/lifecycle_tests.cpp diff --git a/README.md b/README.md index a817c2fd..c6cf541a 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,7 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/memory_hybrid.md`](.planning/architecture/memory_hybrid.md) - [`.planning/architecture/memory_kv.md`](.planning/architecture/memory_kv.md) - [`.planning/architecture/memory_recurrent.md`](.planning/architecture/memory_recurrent.md) +- [`.planning/architecture/memory_streaming.md`](.planning/architecture/memory_streaming.md) - [`.planning/architecture/model_loader.md`](.planning/architecture/model_loader.md) - [`.planning/architecture/model_tensor.md`](.planning/architecture/model_tensor.md) - [`.planning/architecture/model_tensor_window.md`](.planning/architecture/model_tensor_window.md) @@ -252,4 +253,4 @@ Generated from `scripts/embedded_size.sh --snapshot-update` using final dead-str - Ratio (`emel / reference`) stripped: `1.457x` - Ratio (`emel / reference`) section: `0.428x` -This is a matched Qwen3-0.6B end-to-end runner size measurement for the maintained `hello` -> first-token path, not a whole-product feature-parity claim. Both binaries still include the platform runtime selected by the toolchain. \ No newline at end of file +This is a matched Qwen3-0.6B end-to-end runner size measurement for the maintained `hello` -> first-token path, not a whole-product feature-parity claim. Both binaries still include the platform runtime selected by the toolchain. diff --git a/src/emel/machines.hpp b/src/emel/machines.hpp index 8a55ba27..a9f3cf40 100644 --- a/src/emel/machines.hpp +++ b/src/emel/machines.hpp @@ -1,11 +1,11 @@ #pragma once #include "emel/batch/planner/sm.hpp" -#include "emel/diarization/sortformer/request/sm.hpp" #include "emel/diarization/sortformer/executor/sm.hpp" #include "emel/diarization/sortformer/pipeline/sm.hpp" -#include "emel/embeddings/generator/sm.hpp" +#include "emel/diarization/sortformer/request/sm.hpp" #include "emel/embeddings/generator/omniembed/sm.hpp" +#include "emel/embeddings/generator/sm.hpp" #include "emel/gguf/loader/sm.hpp" #include "emel/graph/processor/sm.hpp" #include "emel/io/mmap/sm.hpp" @@ -15,6 +15,7 @@ #include "emel/memory/hybrid/sm.hpp" #include "emel/memory/kv/sm.hpp" #include "emel/memory/recurrent/sm.hpp" +#include "emel/memory/streaming/sm.hpp" #include "emel/model/loader/sm.hpp" #include "emel/model/tensor/sm.hpp" #include "emel/speech/codec/mimi/sm.hpp" @@ -54,6 +55,7 @@ using IoStagedRead = emel::io::staged_read::sm; using MemoryHybrid = emel::memory::hybrid::sm; using KvCache = emel::memory::kv::sm; using MemoryRecurrent = emel::memory::recurrent::sm; +using MemoryStreaming = emel::memory::streaming::sm; using ModelLoader = emel::model::loader::sm; using Model = emel::model::loader::sm; using Parser = emel::gguf::loader::sm; diff --git a/src/emel/memory/streaming/actions.hpp b/src/emel/memory/streaming/actions.hpp new file mode 100644 index 00000000..ac3a7aba --- /dev/null +++ b/src/emel/memory/streaming/actions.hpp @@ -0,0 +1,117 @@ +#pragma once + +#include + +#include "emel/error/error.hpp" +#include "emel/memory/streaming/context.hpp" +#include "emel/memory/streaming/errors.hpp" +#include "emel/memory/streaming/events.hpp" + +namespace emel::memory::streaming::action { + +enum class window_mode : uint8_t { + empty, + filling, + full, +}; + +enum class cursor_mode : uint8_t { + advance, + wrap, +}; + +inline int32_t error_code(const error value) noexcept { + return static_cast(emel::error::cast(value)); +} + +struct effect_initialize { + void operator()(const event::initialize &ev, context &ctx) const noexcept { + ctx.next_logical_position = 0; + ctx.next_physical_position = 0; + ev.error_out = error_code(error::none); + } +}; + +template +struct effect_advance { + void operator()(const event::advance &ev, context &ctx) const noexcept { + const int64_t logical_position = ctx.next_logical_position; + const int32_t physical_position = ctx.next_physical_position; + const int64_t logical_end = logical_position + 1; + int32_t next_physical_position = physical_position + 1; + + if constexpr (resulting_cursor == cursor_mode::wrap) { + next_physical_position = 0; + } + + ev.result.logical_position = logical_position; + ev.result.physical_position = physical_position; + ev.result.window.logical_end = logical_end; + ev.result.window.next_physical_position = next_physical_position; + ev.result.window.capacity = ctx.capacity; + + if constexpr (resulting_window == window_mode::full) { + ev.result.window.logical_begin = + logical_end - static_cast(ctx.capacity); + ev.result.window.physical_begin = next_physical_position; + ev.result.window.valid_positions = ctx.capacity; + } else { + ev.result.window.logical_begin = 0; + ev.result.window.physical_begin = 0; + ev.result.window.valid_positions = static_cast(logical_end); + } + + ctx.next_logical_position = logical_end; + ctx.next_physical_position = next_physical_position; + ev.error_out = error_code(error::none); + } +}; + +struct effect_reset { + void operator()(const event::reset &ev, context &ctx) const noexcept { + ctx.next_logical_position = 0; + ctx.next_physical_position = 0; + ev.error_out = error_code(error::none); + } +}; + +template struct effect_capture_view { + void operator()(const event::capture_view &ev, + const context &ctx) const noexcept { + ev.view_out.logical_end = ctx.next_logical_position; + ev.view_out.next_physical_position = ctx.next_physical_position; + ev.view_out.capacity = ctx.capacity; + + if constexpr (current_window == window_mode::empty) { + ev.view_out.logical_begin = 0; + ev.view_out.physical_begin = 0; + ev.view_out.valid_positions = 0; + } else if constexpr (current_window == window_mode::filling) { + ev.view_out.logical_begin = 0; + ev.view_out.physical_begin = 0; + ev.view_out.valid_positions = + static_cast(ctx.next_logical_position); + } else { + ev.view_out.logical_begin = + ctx.next_logical_position - static_cast(ctx.capacity); + ev.view_out.physical_begin = ctx.next_physical_position; + ev.view_out.valid_positions = ctx.capacity; + } + + ev.error_out = error_code(error::none); + } +}; + +template struct effect_reject { + template + void operator()(const event_type &ev, const context &) const noexcept { + ev.error_out = error_code(error_value); + } +}; + +struct effect_unexpected { + template + void operator()(const event_type &, const context &) const noexcept {} +}; + +} // namespace emel::memory::streaming::action diff --git a/src/emel/memory/streaming/context.hpp b/src/emel/memory/streaming/context.hpp new file mode 100644 index 00000000..0d2c18c6 --- /dev/null +++ b/src/emel/memory/streaming/context.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +namespace emel::memory::streaming { + +struct dependencies { + int32_t capacity; +}; + +namespace action { + +struct context { + explicit context(const dependencies &deps) noexcept + : capacity(deps.capacity) {} + + // Persistent source state is deliberately minimal. Fill/full is represented + // by SML state, and visible-window bounds are derived into event outputs. + const int32_t capacity; + int64_t next_logical_position = 0; + + // This is derivable as next_logical_position % capacity, but retaining the + // cursor removes a 64-bit remainder from every hot streaming advance. The + // transition actions maintain the equivalence invariant. + int32_t next_physical_position = 0; +}; + +} // namespace action + +} // namespace emel::memory::streaming diff --git a/src/emel/memory/streaming/errors.hpp b/src/emel/memory/streaming/errors.hpp new file mode 100644 index 00000000..19df8029 --- /dev/null +++ b/src/emel/memory/streaming/errors.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "emel/error/error.hpp" + +namespace emel::memory::streaming { + +enum class error : emel::error::type { + none = 0u, + invalid_configuration = (1u << 0), + uninitialized = (1u << 1), + already_initialized = (1u << 2), + position_overflow = (1u << 3), + internal_error = (1u << 4), +}; + +} // namespace emel::memory::streaming diff --git a/src/emel/memory/streaming/events.hpp b/src/emel/memory/streaming/events.hpp new file mode 100644 index 00000000..2fbec107 --- /dev/null +++ b/src/emel/memory/streaming/events.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include + +namespace emel::memory::streaming { + +// Half-open logical window [logical_begin, logical_end). physical_begin is +// the ring slot holding logical_begin; next_physical_position is the slot the +// next successful advance will overwrite. These values are derived at the +// event boundary and are never mirrored into persistent actor context. +struct window_view { + int64_t logical_begin = 0; + int64_t logical_end = 0; + int32_t physical_begin = 0; + int32_t next_physical_position = 0; + int32_t valid_positions = 0; + int32_t capacity = 0; +}; + +struct advance_result { + int64_t logical_position = -1; + int32_t physical_position = -1; + window_view window = {}; +}; + +namespace event { + +struct initialize { + int32_t &error_out; +}; + +struct advance { + advance_result &result; + int32_t &error_out; +}; + +struct reset { + int32_t &error_out; +}; + +struct capture_view { + window_view &view_out; + int32_t &error_out; +}; + +} // namespace event + +} // namespace emel::memory::streaming diff --git a/src/emel/memory/streaming/guards.hpp b/src/emel/memory/streaming/guards.hpp new file mode 100644 index 00000000..db711f43 --- /dev/null +++ b/src/emel/memory/streaming/guards.hpp @@ -0,0 +1,76 @@ +#pragma once + +#include +#include + +#include "emel/memory/streaming/context.hpp" + +namespace emel::memory::streaming::guard { + +struct guard_configuration_valid { + bool operator()(const action::context &ctx) const noexcept { + return ctx.capacity > 0; + } +}; + +struct guard_configuration_invalid { + bool operator()(const action::context &ctx) const noexcept { + return !guard_configuration_valid{}(ctx); + } +}; + +struct guard_capacity_one { + bool operator()(const action::context &ctx) const noexcept { + return ctx.capacity == 1; + } +}; + +struct guard_capacity_many { + bool operator()(const action::context &ctx) const noexcept { + return ctx.capacity > 1; + } +}; + +struct guard_filling_remains_partial { + bool operator()(const action::context &ctx) const noexcept { + return ctx.next_logical_position + 1 < static_cast(ctx.capacity); + } +}; + +struct guard_filling_becomes_full { + bool operator()(const action::context &ctx) const noexcept { + return ctx.next_logical_position + 1 == static_cast(ctx.capacity); + } +}; + +struct guard_full_position_available_before_wrap { + bool operator()(const action::context &ctx) const noexcept { + return ctx.next_logical_position < std::numeric_limits::max() && + ctx.next_physical_position >= 0 && + ctx.next_physical_position < ctx.capacity - 1; + } +}; + +struct guard_full_position_available_at_wrap { + bool operator()(const action::context &ctx) const noexcept { + return ctx.next_logical_position < std::numeric_limits::max() && + ctx.next_physical_position >= 0 && + ctx.next_physical_position == ctx.capacity - 1; + } +}; + +struct guard_full_position_overflow { + bool operator()(const action::context &ctx) const noexcept { + return ctx.next_logical_position == std::numeric_limits::max(); + } +}; + +struct guard_full_cursor_invalid { + bool operator()(const action::context &ctx) const noexcept { + return ctx.next_logical_position < std::numeric_limits::max() && + (ctx.next_physical_position < 0 || + ctx.next_physical_position >= ctx.capacity); + } +}; + +} // namespace emel::memory::streaming::guard diff --git a/src/emel/memory/streaming/sm.hpp b/src/emel/memory/streaming/sm.hpp new file mode 100644 index 00000000..ee47687d --- /dev/null +++ b/src/emel/memory/streaming/sm.hpp @@ -0,0 +1,192 @@ +#pragma once + +// benchmark: designed + +#include + +#include "emel/memory/streaming/actions.hpp" +#include "emel/memory/streaming/context.hpp" +#include "emel/memory/streaming/events.hpp" +#include "emel/memory/streaming/guards.hpp" +#include "emel/sm.hpp" + +namespace emel::memory::streaming { + +struct state_uninitialized {}; +struct state_empty {}; +struct state_filling {}; +struct state_full {}; +struct state_errored {}; + +/* +streaming memory architecture notes (single source of truth) + +state purpose +- state_uninitialized rejects use until the injected capacity is validated. +- state_empty represents an initialized ring with no visible history. +- state_filling represents 0 < visible positions < capacity. +- state_full represents a capacity-sized rolling window. +- state_errored makes an unexpected external event observable until a valid + initialize event recovers the actor. + +control invariants +- one actor instance owns one temporal ring. Independent temporal and depformer + caches compose as independent actors, so stream ids, active bits, ownership + maps, free stacks, and per-slot reference actors are unnecessary here. +- actor state, rather than context flags, owns empty/filling/full behavior. +- context stores only the absolute next logical position and a cached physical + cursor; valid length and window bounds are derived into event outputs. +- every fill, full, wrap, overflow, reset, and error choice is an explicit + guard/transition. Actions execute only the already-selected cursor update. +- reset is O(1): stale payload bytes are excluded by the empty state and are + overwritten on later advances, so the actor never scans or clears storage. + +guard semantics and action side effects +- capacity guards validate the constructor-injected ring geometry. +- filling guards select partial versus first-full publication. +- full guards select cursor increment, cursor wrap, overflow, or invariant + failure without action-local runtime branching. +- successful advance actions publish the write slot and visible window, then + update both cursors. No action allocates or performs I/O. +*/ +struct model { + auto operator()() const { + namespace sml = stateforward::sml; + + using effect_advance_filling = + action::effect_advance; + using effect_advance_full = + action::effect_advance; + using effect_advance_full_wrap = + action::effect_advance; + + // clang-format off + return sml::make_transition_table( + //------------------------------------------------------------------------------// + // Initialization validates injected capacity. Duplicate initialization + // is explicit and preserves the current ring. + sml::state <= *sml::state + + sml::event [ guard::guard_configuration_valid{} ] + / action::effect_initialize{} + , sml::state <= sml::state + + sml::event [ guard::guard_configuration_invalid{} ] + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event [ guard::guard_configuration_valid{} ] + / action::effect_initialize{} + , sml::state <= sml::state + + sml::event [ guard::guard_configuration_invalid{} ] + / action::effect_reject{} + + //------------------------------------------------------------------------------// + // Advance from empty or partially filled rings. + , sml::state <= sml::state + + sml::event [ guard::guard_capacity_one{} ] + / effect_advance_full_wrap{} + , sml::state <= sml::state + + sml::event [ guard::guard_capacity_many{} ] + / effect_advance_filling{} + , sml::state <= sml::state + + sml::event [ guard::guard_filling_remains_partial{} ] + / effect_advance_filling{} + , sml::state <= sml::state + + sml::event [ guard::guard_filling_becomes_full{} ] + / effect_advance_full_wrap{} + + //------------------------------------------------------------------------------// + // Full-ring advance explicitly selects increment, wrap, or failure. + , sml::state <= sml::state + + sml::event + [ guard::guard_full_position_available_before_wrap{} ] + / effect_advance_full{} + , sml::state <= sml::state + + sml::event + [ guard::guard_full_position_available_at_wrap{} ] + / effect_advance_full_wrap{} + , sml::state <= sml::state + + sml::event [ guard::guard_full_position_overflow{} ] + / action::effect_reject{} + , sml::state <= sml::state + + sml::event [ guard::guard_full_cursor_invalid{} ] + / action::effect_reject{} + + //------------------------------------------------------------------------------// + // O(1) reset and derived view publication. + , sml::state <= sml::state + + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event + / action::effect_capture_view{} + , sml::state <= sml::state + + sml::event + / action::effect_capture_view{} + , sml::state <= sml::state + + sml::event + / action::effect_capture_view{} + + //------------------------------------------------------------------------------// + // Known operations before initialization are explicit failures. + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + + //------------------------------------------------------------------------------// + // Every external event outside the public contract is explicit. + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + ); + // clang-format on + } +}; + +struct sm : public emel::sm { + using base_type = emel::sm; + using base_type::is; + using base_type::process_event; + using base_type::visit_current_states; + + explicit sm(const dependencies &deps) : base_type(std::in_place, deps) {} +}; + +using Streaming = sm; + +} // namespace emel::memory::streaming diff --git a/tests/memory/streaming/lifecycle_tests.cpp b/tests/memory/streaming/lifecycle_tests.cpp new file mode 100644 index 00000000..7b2f3f9f --- /dev/null +++ b/tests/memory/streaming/lifecycle_tests.cpp @@ -0,0 +1,232 @@ +#include +#include + +#include + +#include "../../allocation_tracker.hpp" +#include "emel/error/error.hpp" +#include "emel/memory/streaming/guards.hpp" +#include "emel/memory/streaming/sm.hpp" + +namespace { + +namespace streaming = emel::memory::streaming; +namespace sml = stateforward::sml; + +int32_t error_code(const streaming::error value) noexcept { + return static_cast(emel::error::cast(value)); +} + +struct fixture { + explicit fixture(const int32_t capacity) + : machine(streaming::dependencies{.capacity = capacity}) {} + + bool initialize() { + err = error_code(streaming::error::none); + return machine.process_event( + streaming::event::initialize{.error_out = err}); + } + + bool advance() { + err = error_code(streaming::error::none); + return machine.process_event( + streaming::event::advance{.result = result, .error_out = err}); + } + + bool reset() { + err = error_code(streaming::error::none); + return machine.process_event(streaming::event::reset{.error_out = err}); + } + + bool capture() { + err = error_code(streaming::error::none); + return machine.process_event( + streaming::event::capture_view{.view_out = view, .error_out = err}); + } + + streaming::sm machine; + streaming::advance_result result = {}; + streaming::window_view view = {}; + int32_t err = error_code(streaming::error::none); +}; + +void check_window(const streaming::window_view &view, + const int64_t logical_begin, const int64_t logical_end, + const int32_t physical_begin, const int32_t next_physical, + const int32_t valid_positions, const int32_t capacity) { + CHECK(view.logical_begin == logical_begin); + CHECK(view.logical_end == logical_end); + CHECK(view.physical_begin == physical_begin); + CHECK(view.next_physical_position == next_physical); + CHECK(view.valid_positions == valid_positions); + CHECK(view.capacity == capacity); +} + +void check_advance(const fixture &state, const int64_t logical_position, + const int32_t physical_position, const int64_t logical_begin, + const int64_t logical_end, const int32_t physical_begin, + const int32_t next_physical, const int32_t valid_positions, + const int32_t capacity) { + CHECK(state.result.logical_position == logical_position); + CHECK(state.result.physical_position == physical_position); + check_window(state.result.window, logical_begin, logical_end, physical_begin, + next_physical, valid_positions, capacity); +} + +} // namespace + +TEST_CASE("memory streaming rejects invalid injected capacity") { + fixture state{0}; + + CHECK(state.initialize()); + CHECK(state.err == error_code(streaming::error::invalid_configuration)); + CHECK(state.machine.is(sml::state)); +} + +TEST_CASE("memory streaming fills then wraps a fixed ring") { + fixture state{3}; + + REQUIRE(state.initialize()); + CHECK(state.machine.is(sml::state)); + REQUIRE(state.capture()); + check_window(state.view, 0, 0, 0, 0, 0, 3); + + REQUIRE(state.advance()); + check_advance(state, 0, 0, 0, 1, 0, 1, 1, 3); + CHECK(state.machine.is(sml::state)); + + REQUIRE(state.advance()); + check_advance(state, 1, 1, 0, 2, 0, 2, 2, 3); + CHECK(state.machine.is(sml::state)); + REQUIRE(state.capture()); + check_window(state.view, 0, 2, 0, 2, 2, 3); + + REQUIRE(state.advance()); + check_advance(state, 2, 2, 0, 3, 0, 0, 3, 3); + CHECK(state.machine.is(sml::state)); + + REQUIRE(state.advance()); + check_advance(state, 3, 0, 1, 4, 1, 1, 3, 3); + + REQUIRE(state.advance()); + check_advance(state, 4, 1, 2, 5, 2, 2, 3, 3); + + REQUIRE(state.advance()); + check_advance(state, 5, 2, 3, 6, 0, 0, 3, 3); + + REQUIRE(state.capture()); + check_window(state.view, 3, 6, 0, 0, 3, 3); +} + +TEST_CASE("memory streaming capacity one stays full and overwrites one slot") { + fixture state{1}; + + REQUIRE(state.initialize()); + REQUIRE(state.advance()); + check_advance(state, 0, 0, 0, 1, 0, 0, 1, 1); + CHECK(state.machine.is(sml::state)); + + REQUIRE(state.advance()); + check_advance(state, 1, 0, 1, 2, 0, 0, 1, 1); +} + +TEST_CASE( + "memory streaming reset invalidates history without clearing storage") { + fixture state{2}; + + REQUIRE(state.initialize()); + REQUIRE(state.advance()); + REQUIRE(state.advance()); + REQUIRE(state.advance()); + REQUIRE(state.reset()); + CHECK(state.machine.is(sml::state)); + + REQUIRE(state.capture()); + check_window(state.view, 0, 0, 0, 0, 0, 2); + + REQUIRE(state.advance()); + check_advance(state, 0, 0, 0, 1, 0, 1, 1, 2); +} + +TEST_CASE( + "memory streaming models uninitialized and duplicate initialize errors") { + fixture state{4}; + + CHECK(state.advance()); + CHECK(state.err == error_code(streaming::error::uninitialized)); + CHECK(state.reset()); + CHECK(state.err == error_code(streaming::error::uninitialized)); + CHECK(state.capture()); + CHECK(state.err == error_code(streaming::error::uninitialized)); + + REQUIRE(state.initialize()); + CHECK(state.initialize()); + CHECK(state.err == error_code(streaming::error::already_initialized)); + CHECK(state.machine.is(sml::state)); +} + +TEST_CASE("memory streaming dispatch remains allocation free") { + fixture state{8}; + REQUIRE(state.initialize()); + + emel::test::allocation::allocation_scope allocations; + for (int32_t index = 0; index < 64; ++index) { + REQUIRE(state.advance()); + } + REQUIRE(state.capture()); + REQUIRE(state.reset()); + + CHECK(allocations.allocations() == 0u); +} + +TEST_CASE( + "memory streaming makes unexpected events observable and recoverable") { + struct unknown_event {}; + + fixture state{3}; + REQUIRE(state.initialize()); + CHECK(state.machine.process_event(unknown_event{})); + CHECK(state.machine.is(sml::state)); + + CHECK(state.capture()); + CHECK(state.err == error_code(streaming::error::internal_error)); + REQUIRE(state.initialize()); + CHECK(state.machine.is(sml::state)); +} + +TEST_CASE("memory streaming full-state invariant failures are explicit") { + streaming::action::context ctx{streaming::dependencies{.capacity = 3}}; + stateforward::sml::sm machine{ + ctx}; + machine.set_current_states(sml::state); + + streaming::advance_result result = {}; + int32_t err = error_code(streaming::error::none); + + ctx.next_logical_position = std::numeric_limits::max(); + ctx.next_physical_position = 0; + CHECK(machine.process_event( + streaming::event::advance{.result = result, .error_out = err})); + CHECK(err == error_code(streaming::error::position_overflow)); + + ctx.next_logical_position = 3; + ctx.next_physical_position = -1; + err = error_code(streaming::error::none); + CHECK(machine.process_event( + streaming::event::advance{.result = result, .error_out = err})); + CHECK(err == error_code(streaming::error::internal_error)); + + ctx.next_physical_position = std::numeric_limits::max(); + err = error_code(streaming::error::none); + CHECK(machine.process_event( + streaming::event::advance{.result = result, .error_out = err})); + CHECK(err == error_code(streaming::error::internal_error)); + + const streaming::guard::guard_full_cursor_invalid cursor_invalid{}; + ctx.next_logical_position = std::numeric_limits::max(); + ctx.next_physical_position = 0; + CHECK_FALSE(cursor_invalid(ctx)); + + ctx.next_logical_position = 3; + CHECK_FALSE(cursor_invalid(ctx)); +} From 9f097dbbcfbc4b3467bd9efdfcb1ba160563bc70 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 02:14:30 -0500 Subject: [PATCH 08/61] refactor: delegate Moshi cache positions to streaming actors --- .../mermaid/speech_generator_moshi.mmd | 195 ++++++ .../speech_generator_moshi_executor.mmd | 288 +++++++++ ...ch_generator_moshi_personaplex_session.mmd | 72 +++ .../architecture/speech_generator_moshi.md | 400 ++++++++++++ .../speech_generator_moshi_executor.md | 586 ++++++++++++++++++ ...ech_generator_moshi_personaplex_session.md | 154 +++++ CMakeLists.txt | 1 + README.md | 3 + .../generator/moshi/executor/actions.hpp | 152 +++-- .../speech/generator/moshi/executor/any.hpp | 9 + .../generator/moshi/executor/context.hpp | 22 +- .../generator/moshi/executor/detail.hpp | 24 - .../generator/moshi/executor/events.hpp | 13 +- .../generator/moshi/executor/guards.hpp | 141 +++-- .../speech/generator/moshi/executor/sm.hpp | 68 +- .../moshi/personaplex/session/actions.hpp | 22 + .../moshi/personaplex/session/context.hpp | 10 +- .../moshi/personaplex/session/errors.hpp | 1 + .../moshi/personaplex/session/guards.hpp | 4 - .../moshi/personaplex/session/sm.hpp | 22 +- .../moshi_executor_streaming_tests.cpp | 139 +++++ .../generator/moshi_lifecycle_tests.cpp | 91 ++- .../moshi_personaplex_session_tests.cpp | 22 - .../bench/speech/personaplex_emel_runner.cpp | 6 - 24 files changed, 2239 insertions(+), 206 deletions(-) create mode 100644 .planning/architecture/mermaid/speech_generator_moshi.mmd create mode 100644 .planning/architecture/mermaid/speech_generator_moshi_executor.mmd create mode 100644 .planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd create mode 100644 .planning/architecture/speech_generator_moshi.md create mode 100644 .planning/architecture/speech_generator_moshi_executor.md create mode 100644 .planning/architecture/speech_generator_moshi_personaplex_session.md create mode 100644 tests/speech/generator/moshi_executor_streaming_tests.cpp diff --git a/.planning/architecture/mermaid/speech_generator_moshi.mmd b/.planning/architecture/mermaid/speech_generator_moshi.mmd new file mode 100644 index 00000000..f8a906ac --- /dev/null +++ b/.planning/architecture/mermaid/speech_generator_moshi.mmd @@ -0,0 +1,195 @@ +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none + state_bind_contract_decision --> state_binding : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ + state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ + state_binding --> state_lmgen_mode_decision : completion_initialize_run_ [always] / none + state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_personaplex_lmgen_] / effect_configure_personaplex_lmgen_ + state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_standard_lmgen_] / effect_configure_standard_lmgen_ + state_configure_lmgen --> state_reserve_memory : completion_initialize_run_ [always] / effect_reserve_memory_ + state_reserve_memory --> state_reserve_memory_decision : completion_initialize_run_ [always] / none + state_reserve_memory_decision --> state_allocate_sequence : completion_initialize_run_ [guard_memory_accepted_] / effect_allocate_sequence_ + state_reserve_memory_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ + state_allocate_sequence --> state_allocate_sequence_decision : completion_initialize_run_ [always] / none + state_allocate_sequence_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_memory_accepted_] / none + state_allocate_sequence_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_done_ + state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / none + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / none + state_session_ready --> state_voice_request_decision : load_voice_run [always] / none + state_voice_request_decision --> state_voice_error_out_decision : completion_load_voice_run_ [guard_voice_contract_valid_] / effect_bind_voice_contract_ + state_voice_request_decision --> state_voice_failed_error_out_decision : completion_load_voice_run_ [guard_voice_contract_invalid_] / load_voice_run__ + state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ + state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none + state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ + state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / none + state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_done_ + state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none + state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ + state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none + state_session_ready --> state_prefill_voice_request_decision : prefill_voice_run [always] / none + state_prefill_voice_request_decision --> state_prefill_voice_allocate_slot : completion_prefill_voice_run_ [guard_voice_prefill_request_valid_] / effect_allocate_voice_prefill_slot_ + state_prefill_voice_request_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_prefill_request_invalid_] / prefill_voice_run__ + state_prefill_voice_allocate_slot --> state_prefill_voice_allocate_slot_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_allocate_slot_decision --> state_prefill_voice_capture_memory : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_capture_voice_prefill_memory_ + state_prefill_voice_allocate_slot_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ + state_prefill_voice_capture_memory --> state_prefill_voice_capture_memory_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_capture_memory_decision --> state_prefill_voice_begin : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_begin_voice_prefill_ + state_prefill_voice_capture_memory_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ + state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f32_] / effect_load_voice_embedding_frame_f32_ + state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f16_] / effect_load_voice_embedding_frame_f16_ + state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_bf16_] / effect_load_voice_embedding_frame_bf16_ + state_prefill_voice_embedding_frame --> state_prefill_voice_embedding_frame_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_embedding_frame_decision --> state_prefill_voice_graph_runtime_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_loaded_] / none + state_prefill_voice_embedding_frame_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_failed_] / prefill_voice_run__ + state_prefill_voice_graph_runtime_decision --> state_prefill_voice_running_graph : completion_prefill_voice_run_ [guard_graph_runtime_available_] / effect_run_voice_graph_runtime_ + state_prefill_voice_graph_runtime_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_runtime_unavailable_] / prefill_voice_run__ + state_prefill_voice_running_graph --> state_prefill_voice_graph_error_out_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ + state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_no_graph_error_out_] / none + state_prefill_voice_graph_result_decision --> state_prefill_voice_advance : completion_prefill_voice_run_ [guard_graph_step_accepted_] / effect_advance_voice_prefill_ + state_prefill_voice_graph_result_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_step_rejected_] / prefill_voice_run__ + state_prefill_voice_advance --> state_prefill_voice_complete_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_complete_] / effect_copy_voice_cache_ + state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_pending_] / none + state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_has_voice_complete_out_] / effect_store_voice_complete_out_ + state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_no_voice_complete_out_] / none + state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_has_voice_remaining_out_] / effect_store_voice_remaining_out_ + state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_no_voice_remaining_out_] / none + state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ + state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ + state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_done_ + state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ + state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_session_ready --> state_personaplex_prompt_begin_decision : begin_personaplex_prompt_run [always] / none + state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_nonempty_valid_] / effect_bind_personaplex_prompt_ + state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_empty_valid_] / effect_bind_empty_personaplex_prompt_ + state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_failed_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_invalid_] / begin_personaplex_prompt_run__ + state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ + state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ + state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_done_ + state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ + state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_session_ready --> state_prefill_personaplex_prompt_request_decision : prefill_personaplex_prompt_run [always] / none + state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_allocate_slot : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_valid_] / effect_allocate_personaplex_prompt_slot_ + state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_invalid_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_allocate_slot --> state_prefill_personaplex_prompt_allocate_slot_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_capture_memory : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_capture_personaplex_prompt_memory_ + state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_capture_memory --> state_prefill_personaplex_prompt_capture_memory_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_begin : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_begin_personaplex_prompt_prefill_ + state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_begin --> state_prefill_personaplex_prompt_phase_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pre_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_text_pending_] / effect_build_personaplex_prompt_text_frame_ + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_post_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_phase_invalid_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_frame --> state_prefill_personaplex_prompt_write_input : completion_prefill_personaplex_prompt_run_ [always] / effect_write_and_build_personaplex_prompt_input_ + state_prefill_personaplex_prompt_write_input --> state_prefill_personaplex_prompt_graph_runtime_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_running_graph : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_available_] / effect_run_personaplex_prompt_graph_runtime_ + state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_unavailable_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_running_graph --> state_prefill_personaplex_prompt_graph_error_out_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ + state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_no_graph_error_out_] / none + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_pre_silence_] / effect_advance_personaplex_prompt_pre_silence_ + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_text_] / effect_advance_personaplex_prompt_text_ + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_post_silence_] / effect_advance_personaplex_prompt_post_silence_ + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_step_rejected_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_advance --> state_prefill_personaplex_prompt_complete_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_complete_] / effect_finish_personaplex_prompt_ + state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pending_] / effect_publish_personaplex_prompt_pending_ + state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_complete_out_] / effect_store_personaplex_prompt_complete_out_ + state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_complete_out_] / none + state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_remaining_out_] / effect_store_personaplex_prompt_remaining_out_ + state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_remaining_out_] / none + state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_done_ + state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ + state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_session_ready --> state_step_request_decision : step_run [always] / none + state_step_request_decision --> state_allocate_step_slot : completion_step_run_ [guard_step_request_valid_] / effect_allocate_step_slot_ + state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_blocked_by_voice_prompt_] / effect_mark_voice_prompt_pending_ + state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_request_shape_invalid_] / effect_mark_step_request_invalid_ + state_allocate_step_slot --> state_allocate_step_slot_decision : completion_step_run_ [always] / none + state_allocate_step_slot_decision --> state_capture_memory : completion_step_run_ [guard_memory_accepted_] / effect_capture_memory_ + state_allocate_step_slot_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ + state_capture_memory --> state_capture_memory_decision : completion_step_run_ [always] / none + state_capture_memory_decision --> state_step_begin : completion_step_run_ [guard_memory_accepted_] / effect_begin_step_ + state_capture_memory_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ + state_step_begin --> state_input_write_decision : completion_step_run_ [always] / none + state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_full_input_] / effect_write_full_input_ + state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_tail_input_] / effect_write_tail_input_ + state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_no_input_write_] / none + state_build_input_sequence --> state_graph_runtime_decision : completion_step_run_ [always] / effect_build_input_sequence_ + state_graph_runtime_decision --> state_running_graph : completion_step_run_ [guard_graph_runtime_available_] / effect_run_graph_runtime_ + state_graph_runtime_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_runtime_unavailable_] / step_run__ + state_running_graph --> state_graph_error_out_decision : completion_step_run_ [always] / none + state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ + state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_no_graph_error_out_] / none + state_graph_result_decision --> state_depformer_decision : completion_step_run_ [guard_graph_step_accepted_] / none + state_graph_result_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_step_rejected_] / step_run__ + state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_replace_depformer_tokens_] / effect_replace_audio_with_zero_ + state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_use_graph_audio_tokens_] / none + state_apply_delay_mask --> state_write_generated_decision : completion_step_run_ [always] / effect_apply_delay_mask_and_advance_ + state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_should_write_generated_] / effect_write_generated_ + state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_provided_input_] / effect_write_generated_missing_ + state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_skip_pending_] / effect_consume_skip_ + state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_before_delay_] / effect_publish_no_output_ + state_skip_delay_decision --> state_collect_output : completion_step_run_ [guard_past_delay_] / effect_collect_delayed_output_ + state_collect_output --> state_output_decision : completion_step_run_ [always] / none + state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_has_ungenerated_] / effect_publish_no_output_ + state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_complete_] / effect_publish_output_ + state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_has_produced_out_] / effect_store_produced_out_ + state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_no_produced_out_] / none + state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / step_run__ + state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / none + state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / step_run__ + state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / none + state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_done_ + state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none + state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_error_ + state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none + state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / step_run__ + state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / step_run__ + state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / none + state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / effect_emit_step_error_ + state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / none + state_uninitialized --> state_uninit_voice_error_out_decision : load_voice_run [always] / load_voice_run__ + state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ + state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none + state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ + state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / none + state_uninitialized --> state_uninit_prefill_voice_error_out_decision : prefill_voice_run [always] / prefill_voice_run__ + state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ + state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ + state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_uninitialized --> state_uninit_begin_personaplex_prompt_error_out_decision : begin_personaplex_prompt_run [always] / begin_personaplex_prompt_run__ + state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ + state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ + state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_uninitialized --> state_uninit_prefill_personaplex_prompt_error_out_decision : prefill_personaplex_prompt_run [always] / prefill_personaplex_prompt_run__ + state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ + state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ + state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_session_ready --> state_uninitialized : reset_run [always] / effect_reset_session_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ diff --git a/.planning/architecture/mermaid/speech_generator_moshi_executor.mmd b/.planning/architecture/mermaid/speech_generator_moshi_executor.mmd new file mode 100644 index 00000000..193c6cc8 --- /dev/null +++ b/.planning/architecture/mermaid/speech_generator_moshi_executor.mmd @@ -0,0 +1,288 @@ +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none + state_bind_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ + state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ + state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ + state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ + state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ + state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_exceeds_card_] / effect_bind_full_card_text_sampling_top_k_ + state_audio_sampling_top_k_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_audio_sampling_top_k_within_card_] / effect_bind_requested_audio_sampling_top_k_ + state_audio_sampling_top_k_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_audio_sampling_top_k_exceeds_card_] / effect_bind_full_card_audio_sampling_top_k_ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_callback_decision --> state_ready : completion_initialize_run_ [guard_has_initialize_done_callback_] / effect_emit_initialize_done_ + state_init_callback_decision --> state_ready : completion_initialize_run_ [guard_no_initialize_done_callback_] / none + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [guard_has_initialize_error_callback_] / effect_emit_initialize_error_ + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [guard_no_initialize_error_callback_] / none + state_ready --> state_step_model_decision : step_run [always] / none + state_step_model_decision --> state_step_shape_decision : completion_step_run_ [guard_step_model_matches_] / none + state_step_model_decision --> state_step_error_out_decision : completion_step_run_ [guard_step_model_mismatch_] / effect_mark_model_mismatch_ + state_step_shape_decision --> state_step_execution_decision : completion_step_run_ [guard_step_shape_valid_] / none + state_step_shape_decision --> state_step_error_out_decision : completion_step_run_ [guard_step_shape_invalid_] / effect_mark_request_shape_ + state_step_execution_decision --> state_input_embedding : completion_step_run_ [guard_input_embedding_supported_] / effect_begin_input_embedding_ + state_step_execution_decision --> state_step_error_out_decision : completion_step_run_ [guard_input_embedding_unsupported_] / effect_mark_graph_execution_unsupported_ + state_input_embedding --> state_input_embedding_result_decision : completion_step_run_ [guard_external_input_embedding_supported_] / effect_apply_external_input_embedding_ + state_input_embedding --> state_input_text_embedding_bind : completion_step_run_ [guard_token_input_embedding_supported_] / effect_bind_input_text_embedding_ + state_input_embedding --> state_step_error_out_decision : completion_step_run_ [guard_token_input_embedding_unsupported_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_bind --> state_input_text_embedding_bind_result_decision : completion_step_run_ [always] / none + state_input_text_embedding_bind_result_decision --> state_input_text_embedding_row : completion_step_run_ [guard_embedding_view_bound_] / effect_run_embedding_row_fetch_ + state_input_text_embedding_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_row --> state_input_text_embedding_row_result_decision : completion_step_run_ [always] / none + state_input_text_embedding_row_result_decision --> state_input_text_embedding_apply : completion_step_run_ [guard_embedding_row_succeeded_] / effect_apply_input_text_embedding_row_ + state_input_text_embedding_row_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_row_failed_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_apply --> state_input_text_embedding_result_decision : completion_step_run_ [guard_input_text_embedding_succeeded_] / none + state_input_text_embedding_apply --> state_step_error_out_decision : completion_step_run_ [guard_input_text_embedding_failed_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_result_decision --> state_input_audio_token_decision : completion_step_run_ [always] / none + state_input_audio_token_decision --> state_input_audio_embedding : completion_step_run_ [guard_current_input_audio_token_present_] / effect_bind_input_audio_embedding_ + state_input_audio_token_decision --> state_input_audio_embedding_result_decision : completion_step_run_ [guard_current_input_audio_token_zero_] / effect_skip_zero_input_audio_embedding_ + state_input_audio_token_decision --> state_step_error_out_decision : completion_step_run_ [guard_current_input_audio_token_unsupported_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding --> state_input_audio_embedding_bind_result_decision : completion_step_run_ [always] / none + state_input_audio_embedding_bind_result_decision --> state_input_audio_embedding_row : completion_step_run_ [guard_embedding_view_bound_] / effect_run_embedding_row_fetch_ + state_input_audio_embedding_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding_row --> state_input_audio_embedding_row_result_decision : completion_step_run_ [always] / none + state_input_audio_embedding_row_result_decision --> state_input_audio_embedding_apply : completion_step_run_ [guard_embedding_row_succeeded_] / effect_apply_input_audio_embedding_row_ + state_input_audio_embedding_row_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_row_failed_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding_apply --> state_input_audio_embedding_result_decision : completion_step_run_ [guard_input_audio_embedding_succeeded_] / none + state_input_audio_embedding_apply --> state_step_error_out_decision : completion_step_run_ [guard_input_audio_embedding_failed_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding_result_decision --> state_input_audio_codebook_advance : completion_step_run_ [guard_more_input_audio_codebooks_] / effect_advance_input_audio_codebook_ + state_input_audio_codebook_advance --> state_input_audio_token_decision : completion_step_run_ [always] / none + state_input_audio_embedding_result_decision --> state_input_embedding_result_decision : completion_step_run_ [guard_input_audio_codebooks_complete_] / effect_finish_input_embedding_ + state_input_embedding_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_input_embedding_failed_] / effect_mark_graph_execution_unsupported_ + state_input_embedding_result_decision --> state_bind_temporal_kv : completion_step_run_ [guard_temporal_kv_binding_present_] / effect_bind_temporal_kv_ + state_input_embedding_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_kv_binding_missing_] / effect_mark_graph_execution_unsupported_ + state_bind_temporal_kv --> state_temporal_kv_result_decision : completion_step_run_ [guard_temporal_kv_bound_] / none + state_bind_temporal_kv --> state_step_error_out_decision : completion_step_run_ [guard_temporal_kv_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_kv_result_decision --> state_temporal_position_result_decision : completion_step_run_ [always] / effect_advance_temporal_position_ + state_temporal_position_result_decision --> state_temporal_position_valid_decision : completion_step_run_ [guard_temporal_position_advance_succeeded_] / none + state_temporal_position_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_position_advance_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_position_valid_decision --> state_temporal_layer_norm : completion_step_run_ [guard_temporal_layer_norm_supported_] / effect_run_temporal_layer_norm_rms_ + state_temporal_position_valid_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm --> state_temporal_layer_norm_rms_result_decision : completion_step_run_ [always] / none + state_temporal_layer_norm_rms_result_decision --> state_temporal_layer_norm_scale : completion_step_run_ [guard_temporal_layer_norm_rms_succeeded_] / effect_run_temporal_layer_norm_scale_ + state_temporal_layer_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm_scale --> state_temporal_layer_norm_result_decision : completion_step_run_ [guard_temporal_layer_norm_succeeded_] / none + state_temporal_layer_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm_result_decision --> state_temporal_layer_projection : completion_step_run_ [guard_temporal_layer_projection_supported_] / effect_bind_temporal_layer_projection_ + state_temporal_layer_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_projection --> state_temporal_layer_projection_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_projection_bind_result_decision --> state_temporal_layer_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_projection_ + state_temporal_layer_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_projection_run --> state_temporal_layer_projection_result_decision : completion_step_run_ [guard_temporal_layer_projection_succeeded_] / none + state_temporal_layer_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_projection_result_decision --> state_temporal_layer_rope : completion_step_run_ [guard_temporal_layer_rope_supported_] / effect_run_temporal_layer_rope_0__ + state_temporal_layer_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_rope_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_rope --> state_temporal_layer_rope_result_decision : completion_step_run_ [guard_temporal_layer_rope_succeeded_] / effect_copy_temporal_layer_rope_0__ + state_temporal_layer_rope --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_rope_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_rope_result_decision --> state_temporal_layer_key_rope : completion_step_run_ [always] / effect_run_temporal_layer_rope_1__ + state_temporal_layer_key_rope --> state_temporal_layer_key_rope_result_decision : completion_step_run_ [guard_temporal_layer_rope_succeeded_] / effect_copy_temporal_layer_rope_1__ + state_temporal_layer_key_rope --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_rope_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_key_rope_result_decision --> state_temporal_layer_cache_write : completion_step_run_ [guard_temporal_layer_cache_write_supported_] / effect_write_temporal_layer_kv_cache_ + state_temporal_layer_key_rope_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_cache_write_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_cache_write --> state_temporal_layer_cache_write_result_decision : completion_step_run_ [guard_temporal_layer_cache_write_succeeded_] / none + state_temporal_layer_cache_write --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_cache_write_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_cache_write_result_decision --> state_temporal_layer_attention : completion_step_run_ [guard_temporal_layer_attention_supported_] / effect_run_temporal_layer_attention_ + state_temporal_layer_cache_write_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_attention_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_attention --> state_temporal_layer_attention_result_decision : completion_step_run_ [guard_temporal_layer_attention_succeeded_] / none + state_temporal_layer_attention --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_attention_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_attention_result_decision --> state_temporal_layer_out_projection : completion_step_run_ [guard_temporal_layer_out_projection_supported_] / effect_bind_temporal_layer_out_projection_ + state_temporal_layer_attention_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_out_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_out_projection --> state_temporal_layer_out_projection_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_out_projection_bind_result_decision --> state_temporal_layer_out_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_out_projection_ + state_temporal_layer_out_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_out_projection_run --> state_temporal_layer_out_projection_result_decision : completion_step_run_ [guard_temporal_layer_out_projection_succeeded_] / none + state_temporal_layer_out_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_out_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_out_projection_result_decision --> state_temporal_layer_residual : completion_step_run_ [always] / effect_apply_temporal_layer_attention_residual_ + state_temporal_layer_residual --> state_temporal_layer_residual_result_decision : completion_step_run_ [guard_temporal_layer_residual_succeeded_] / none + state_temporal_layer_residual --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_residual_result_decision --> state_temporal_layer_norm2 : completion_step_run_ [guard_temporal_layer_norm2_supported_] / effect_run_temporal_layer_norm2_rms_ + state_temporal_layer_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm2_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm2 --> state_temporal_layer_norm2_rms_result_decision : completion_step_run_ [always] / none + state_temporal_layer_norm2_rms_result_decision --> state_temporal_layer_norm2_scale : completion_step_run_ [guard_temporal_layer_norm2_rms_succeeded_] / effect_run_temporal_layer_norm2_scale_ + state_temporal_layer_norm2_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm2_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm2_scale --> state_temporal_layer_norm2_result_decision : completion_step_run_ [guard_temporal_layer_norm2_succeeded_] / none + state_temporal_layer_norm2_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm2_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm2_result_decision --> state_temporal_layer_gating_in : completion_step_run_ [guard_temporal_layer_gating_in_supported_] / effect_bind_temporal_layer_gating_in_ + state_temporal_layer_norm2_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_in_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_in --> state_temporal_layer_gating_in_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_gating_in_bind_result_decision --> state_temporal_layer_gating_in_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_gating_in_ + state_temporal_layer_gating_in_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_in_run --> state_temporal_layer_gating_in_result_decision : completion_step_run_ [guard_temporal_layer_gating_in_succeeded_] / none + state_temporal_layer_gating_in_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_in_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_in_result_decision --> state_temporal_layer_silu_gate : completion_step_run_ [guard_temporal_layer_silu_gate_supported_] / effect_run_temporal_layer_silu_gate_silu_ + state_temporal_layer_gating_in_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_silu_gate_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_silu_gate --> state_temporal_layer_silu_gate_silu_result_decision : completion_step_run_ [always] / none + state_temporal_layer_silu_gate_silu_result_decision --> state_temporal_layer_silu_gate_mul : completion_step_run_ [guard_temporal_layer_silu_gate_silu_succeeded_] / effect_run_temporal_layer_silu_gate_mul_ + state_temporal_layer_silu_gate_silu_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_silu_gate_silu_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_silu_gate_mul --> state_temporal_layer_silu_gate_result_decision : completion_step_run_ [guard_temporal_layer_silu_gate_succeeded_] / none + state_temporal_layer_silu_gate_mul --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_silu_gate_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_silu_gate_result_decision --> state_temporal_layer_gating_out : completion_step_run_ [guard_temporal_layer_gating_out_supported_] / effect_bind_temporal_layer_gating_out_ + state_temporal_layer_silu_gate_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_out_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_out --> state_temporal_layer_gating_out_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_gating_out_bind_result_decision --> state_temporal_layer_gating_out_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_gating_out_ + state_temporal_layer_gating_out_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_out_run --> state_temporal_layer_gating_out_result_decision : completion_step_run_ [guard_temporal_layer_gating_out_succeeded_] / none + state_temporal_layer_gating_out_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_out_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_out_result_decision --> state_temporal_layer_ff_residual : completion_step_run_ [always] / effect_apply_temporal_layer_ff_residual_ + state_temporal_layer_ff_residual --> state_temporal_layer_ff_residual_result_decision : completion_step_run_ [guard_temporal_layer_ff_residual_succeeded_] / none + state_temporal_layer_ff_residual --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_ff_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_ff_residual_result_decision --> state_temporal_layer_advance : completion_step_run_ [guard_more_temporal_layers_] / effect_advance_temporal_layer_ + state_temporal_layer_ff_residual_result_decision --> state_temporal_out_norm : completion_step_run_ [guard_temporal_layers_complete_] / effect_run_temporal_out_norm_rms_ + state_temporal_layer_ff_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_advance --> state_temporal_layer_norm : completion_step_run_ [guard_temporal_layer_norm_supported_] / effect_run_temporal_layer_norm_rms_ + state_temporal_layer_advance --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm --> state_temporal_out_norm_rms_result_decision : completion_step_run_ [always] / none + state_temporal_out_norm_rms_result_decision --> state_temporal_out_norm_scale : completion_step_run_ [guard_temporal_out_norm_rms_succeeded_] / effect_run_temporal_out_norm_scale_ + state_temporal_out_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm_scale --> state_temporal_out_norm_result_decision : completion_step_run_ [guard_temporal_out_norm_succeeded_] / effect_publish_temporal_out_norm_ + state_temporal_out_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm_result_decision --> state_text_logits : completion_step_run_ [guard_text_logits_supported_] / effect_bind_text_token_logits_ + state_temporal_out_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_text_logits --> state_text_logits_bind_result_decision : completion_step_run_ [always] / none + state_text_logits_bind_result_decision --> state_text_logits_sample_projection : completion_step_run_ [guard_forced_text_token_valid_and_sampling_consume_] / effect_compute_text_token_logits_ + state_text_logits_bind_result_decision --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_token_valid_without_sampling_consume_] / effect_publish_forced_text_token_ + state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_forced_text_sampling_config_invalid_] / effect_mark_graph_execution_unsupported_ + state_text_logits_bind_result_decision --> state_text_logits_run : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_argmax_] / effect_select_text_token_ + state_text_logits_bind_result_decision --> state_text_logits_sample_projection : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_sampling_] / effect_compute_text_token_logits_ + state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid_] / effect_mark_graph_execution_unsupported_ + state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_sample_projection --> state_text_logits_sample_projection_result_decision : completion_step_run_ [always] / none + state_text_logits_sample_projection_result_decision --> state_text_logits_sample_scale : completion_step_run_ [guard_text_logits_matmul_succeeded_] / effect_scale_text_sampling_logits_ + state_text_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_sample_scale --> state_text_logits_sample_softmax : completion_step_run_ [always] / effect_compute_text_sampling_probabilities_ + state_text_logits_sample_softmax --> state_text_logits_sample_top_k : completion_step_run_ [always] / effect_compute_text_sampling_top_k_ + state_text_logits_sample_top_k --> state_text_logits_sample_select : completion_step_run_ [always] / effect_select_text_sampling_token_ + state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_sampled_text_token_ready_] / effect_publish_sampled_text_token_ + state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_sampling_consumed_] / effect_publish_forced_text_token_ + state_text_logits_sample_select --> state_step_error_out_decision : completion_step_run_ [guard_text_sampling_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_run --> state_text_logits_result_decision : completion_step_run_ [guard_text_logits_succeeded_] / none + state_text_logits_run --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_result_decision --> state_bind_depformer_kv : completion_step_run_ [guard_depformer_kv_binding_present_] / effect_bind_depformer_kv_ + state_text_logits_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_kv_binding_missing_] / effect_mark_graph_execution_unsupported_ + state_bind_depformer_kv --> state_depformer_kv_result_decision : completion_step_run_ [guard_depformer_kv_bound_] / effect_reset_depformer_positions_ + state_bind_depformer_kv --> state_step_error_out_decision : completion_step_run_ [guard_depformer_kv_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_kv_result_decision --> state_depformer_position_reset_result_decision : completion_step_run_ [always] / none + state_depformer_position_reset_result_decision --> state_depformer_position_advance_result_decision : completion_step_run_ [guard_depformer_position_reset_succeeded_] / effect_advance_depformer_position_ + state_depformer_position_reset_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_position_reset_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_position_advance_result_decision --> state_depformer_weight_route_decision : completion_step_run_ [guard_depformer_position_advance_succeeded_] / none + state_depformer_position_advance_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_position_advance_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_weight_route_decision --> state_depformer_weight_decision : completion_step_run_ [guard_depformer_scheduled_weight_present_] / effect_use_depformer_scheduled_weight_ + state_depformer_weight_route_decision --> state_depformer_weight_decision : completion_step_run_ [guard_depformer_scheduled_weight_absent_] / effect_use_depformer_codebook_weight_ + state_depformer_weight_route_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_scheduled_weight_invalid_] / effect_mark_graph_execution_unsupported_ + state_depformer_weight_decision --> state_depformer_input : completion_step_run_ [guard_depformer_text_input_supported_] / effect_bind_depformer_text_input_projection_ + state_depformer_weight_decision --> state_depformer_input : completion_step_run_ [guard_depformer_audio_input_supported_] / effect_bind_depformer_audio_input_projection_ + state_depformer_weight_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_input --> state_depformer_input_projection_bind_result_decision : completion_step_run_ [always] / none + state_depformer_input_projection_bind_result_decision --> state_depformer_input_projection : completion_step_run_ [guard_depformer_input_projection_bound_] / effect_run_depformer_input_projection_ + state_depformer_input_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_projection_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_projection --> state_depformer_input_projection_result_decision : completion_step_run_ [always] / none + state_depformer_input_projection_result_decision --> state_depformer_input_embedding_bind : completion_step_run_ [guard_depformer_text_input_projection_succeeded_] / effect_bind_depformer_text_input_embedding_ + state_depformer_input_projection_result_decision --> state_depformer_input_embedding_bind : completion_step_run_ [guard_depformer_audio_input_projection_succeeded_] / effect_bind_depformer_audio_input_embedding_ + state_depformer_input_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_projection_embedding_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_embedding_bind --> state_depformer_input_embedding_bind_result_decision : completion_step_run_ [always] / none + state_depformer_input_embedding_bind_result_decision --> state_depformer_input_embedding_row : completion_step_run_ [guard_embedding_view_bound_] / effect_run_embedding_row_fetch_ + state_depformer_input_embedding_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_embedding_row --> state_depformer_input_embedding_row_result_decision : completion_step_run_ [always] / none + state_depformer_input_embedding_row_result_decision --> state_depformer_input_embedding_apply : completion_step_run_ [guard_embedding_row_succeeded_] / effect_apply_depformer_input_embedding_row_ + state_depformer_input_embedding_row_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_row_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_embedding_apply --> state_depformer_input_result_decision : completion_step_run_ [guard_depformer_input_succeeded_] / none + state_depformer_input_embedding_apply --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_result_decision --> state_depformer_layer_norm : completion_step_run_ [guard_depformer_layer_norm_supported_] / effect_run_depformer_layer_norm_rms_ + state_depformer_input_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm --> state_depformer_layer_norm_rms_result_decision : completion_step_run_ [always] / none + state_depformer_layer_norm_rms_result_decision --> state_depformer_layer_norm_scale : completion_step_run_ [guard_depformer_layer_norm_rms_succeeded_] / effect_run_depformer_layer_norm_scale_ + state_depformer_layer_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm_scale --> state_depformer_layer_norm_result_decision : completion_step_run_ [guard_depformer_layer_norm_succeeded_] / none + state_depformer_layer_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm_result_decision --> state_depformer_layer_projection : completion_step_run_ [guard_depformer_layer_projection_supported_] / effect_bind_depformer_layer_projection_ + state_depformer_layer_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_projection --> state_depformer_layer_projection_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_projection_bind_result_decision --> state_depformer_layer_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_projection_ + state_depformer_layer_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_projection_run --> state_depformer_layer_projection_result_decision : completion_step_run_ [guard_depformer_layer_projection_succeeded_] / none + state_depformer_layer_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_projection_result_decision --> state_depformer_layer_cache_write : completion_step_run_ [guard_depformer_layer_cache_write_supported_] / effect_write_depformer_layer_kv_cache_ + state_depformer_layer_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_cache_write_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_cache_write --> state_depformer_layer_cache_write_result_decision : completion_step_run_ [guard_depformer_layer_cache_write_succeeded_] / none + state_depformer_layer_cache_write --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_cache_write_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_cache_write_result_decision --> state_depformer_layer_attention : completion_step_run_ [guard_depformer_layer_attention_supported_] / effect_run_depformer_layer_attention_ + state_depformer_layer_cache_write_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_attention_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_attention --> state_depformer_layer_attention_result_decision : completion_step_run_ [guard_depformer_layer_attention_succeeded_] / none + state_depformer_layer_attention --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_attention_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_attention_result_decision --> state_depformer_layer_out_projection : completion_step_run_ [guard_depformer_layer_out_projection_supported_] / effect_bind_depformer_layer_out_projection_ + state_depformer_layer_attention_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_out_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_out_projection --> state_depformer_layer_out_projection_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_out_projection_bind_result_decision --> state_depformer_layer_out_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_out_projection_ + state_depformer_layer_out_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_out_projection_run --> state_depformer_layer_out_projection_result_decision : completion_step_run_ [guard_depformer_layer_out_projection_succeeded_] / none + state_depformer_layer_out_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_out_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_out_projection_result_decision --> state_depformer_layer_residual : completion_step_run_ [always] / effect_apply_depformer_layer_attention_residual_ + state_depformer_layer_residual --> state_depformer_layer_residual_result_decision : completion_step_run_ [guard_depformer_layer_residual_succeeded_] / none + state_depformer_layer_residual --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_residual_result_decision --> state_depformer_layer_norm2 : completion_step_run_ [guard_depformer_layer_norm2_supported_] / effect_run_depformer_layer_norm2_rms_ + state_depformer_layer_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm2_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm2 --> state_depformer_layer_norm2_rms_result_decision : completion_step_run_ [always] / none + state_depformer_layer_norm2_rms_result_decision --> state_depformer_layer_norm2_scale : completion_step_run_ [guard_depformer_layer_norm2_rms_succeeded_] / effect_run_depformer_layer_norm2_scale_ + state_depformer_layer_norm2_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm2_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm2_scale --> state_depformer_layer_norm2_result_decision : completion_step_run_ [guard_depformer_layer_norm2_succeeded_] / none + state_depformer_layer_norm2_scale --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm2_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm2_result_decision --> state_depformer_layer_gating_in : completion_step_run_ [guard_depformer_layer_gating_in_supported_] / effect_bind_depformer_layer_gating_in_ + state_depformer_layer_norm2_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_in_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_in --> state_depformer_layer_gating_in_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_gating_in_bind_result_decision --> state_depformer_layer_gating_in_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_gating_in_ + state_depformer_layer_gating_in_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_in_run --> state_depformer_layer_gating_in_result_decision : completion_step_run_ [guard_depformer_layer_gating_in_succeeded_] / none + state_depformer_layer_gating_in_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_in_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_in_result_decision --> state_depformer_layer_silu_gate : completion_step_run_ [guard_depformer_layer_silu_gate_supported_] / effect_run_depformer_layer_silu_gate_silu_ + state_depformer_layer_gating_in_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_silu_gate_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_silu_gate --> state_depformer_layer_silu_gate_silu_result_decision : completion_step_run_ [always] / none + state_depformer_layer_silu_gate_silu_result_decision --> state_depformer_layer_silu_gate_mul : completion_step_run_ [guard_depformer_layer_silu_gate_silu_succeeded_] / effect_run_depformer_layer_silu_gate_mul_ + state_depformer_layer_silu_gate_silu_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_silu_gate_silu_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_silu_gate_mul --> state_depformer_layer_silu_gate_result_decision : completion_step_run_ [guard_depformer_layer_silu_gate_succeeded_] / none + state_depformer_layer_silu_gate_mul --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_silu_gate_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_silu_gate_result_decision --> state_depformer_layer_gating_out : completion_step_run_ [guard_depformer_layer_gating_out_supported_] / effect_bind_depformer_layer_gating_out_ + state_depformer_layer_silu_gate_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_out_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_out --> state_depformer_layer_gating_out_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_gating_out_bind_result_decision --> state_depformer_layer_gating_out_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_gating_out_ + state_depformer_layer_gating_out_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_out_run --> state_depformer_layer_gating_out_result_decision : completion_step_run_ [guard_depformer_layer_gating_out_succeeded_] / none + state_depformer_layer_gating_out_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_out_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_out_result_decision --> state_depformer_layer_ff_residual : completion_step_run_ [always] / effect_apply_depformer_layer_ff_residual_ + state_depformer_layer_ff_residual --> state_depformer_layer_ff_residual_result_decision : completion_step_run_ [guard_depformer_layer_ff_residual_succeeded_] / none + state_depformer_layer_ff_residual --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_ff_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_ff_residual_result_decision --> state_depformer_layer_advance : completion_step_run_ [guard_more_depformer_layers_] / effect_advance_depformer_layer_ + state_depformer_layer_ff_residual_result_decision --> state_depformer_logits : completion_step_run_ [guard_depformer_logits_supported_] / effect_bind_depformer_token_logits_ + state_depformer_layer_ff_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits --> state_depformer_logits_bind_result_decision : completion_step_run_ [always] / none + state_depformer_logits_bind_result_decision --> state_depformer_logits_run : completion_step_run_ [guard_depformer_logits_projection_bound_argmax_] / effect_select_depformer_token_ + state_depformer_logits_bind_result_decision --> state_depformer_logits_sample_projection : completion_step_run_ [guard_depformer_logits_projection_bound_sampling_] / effect_compute_depformer_token_logits_ + state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_projection_bound_sampling_invalid_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_sample_projection --> state_depformer_logits_sample_projection_result_decision : completion_step_run_ [always] / none + state_depformer_logits_sample_projection_result_decision --> state_depformer_logits_sample_scale : completion_step_run_ [guard_depformer_logits_matmul_succeeded_] / effect_scale_depformer_sampling_logits_ + state_depformer_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_sample_scale --> state_depformer_logits_sample_softmax : completion_step_run_ [always] / effect_compute_depformer_sampling_probabilities_ + state_depformer_logits_sample_softmax --> state_depformer_logits_sample_top_k : completion_step_run_ [always] / effect_compute_depformer_sampling_top_k_ + state_depformer_logits_sample_top_k --> state_depformer_logits_sample_select : completion_step_run_ [always] / effect_select_depformer_sampling_token_ + state_depformer_layer_advance --> state_depformer_layer_norm : completion_step_run_ [guard_depformer_layer_norm_supported_] / effect_run_depformer_layer_norm_rms_ + state_depformer_layer_advance --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_run --> state_depformer_token_publish : completion_step_run_ [guard_depformer_logits_succeeded_] / effect_publish_depformer_token_ + state_depformer_logits_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_sample_select --> state_depformer_token_publish : completion_step_run_ [guard_depformer_sampling_succeeded_] / effect_publish_depformer_token_ + state_depformer_logits_sample_select --> state_step_error_out_decision : completion_step_run_ [guard_depformer_sampling_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_token_publish --> state_depformer_logits_result_decision : completion_step_run_ [always] / none + state_depformer_logits_result_decision --> state_depformer_codebook_advance : completion_step_run_ [guard_more_depformer_codebooks_] / effect_advance_depformer_codebook_ + state_depformer_logits_result_decision --> state_ready : completion_step_run_ [guard_depformer_codebooks_complete_] / none + state_depformer_codebook_advance --> state_depformer_position_advance_result_decision : completion_step_run_ [always] / effect_advance_depformer_position_ + state_step_error_out_decision --> state_ready : completion_step_run_ [step_run__] / step_run__ + state_step_error_out_decision --> state_ready : completion_step_run_ [step_run__] / none + state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / effect_mark_not_initialized_ + state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / step_run__ + state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / none + state_ready --> state_uninitialized : reset [always] / effect_reset_session_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ diff --git a/.planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd b/.planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd new file mode 100644 index 00000000..dcbf3044 --- /dev/null +++ b/.planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd @@ -0,0 +1,72 @@ +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_initialize_temporal_positions_result : initialize_run [guard_initialize_request_valid_] / effect_initialize_temporal_positions_ + state_initialize_temporal_positions_result --> state_initialize_depformer_positions_result : completion_initialize_run_ [initialize_run__] / effect_initialize_depformer_positions_ + state_initialize_temporal_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ + state_initialize_depformer_positions_result --> state_initialize_encoder_result : completion_initialize_run_ [initialize_run__] / effect_initialize_encoder_ + state_initialize_depformer_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ + state_uninitialized --> state_failed : initialize_run [guard_initialize_request_invalid_] / effect_fail_initialize_invalid_ + state_initialize_encoder_result --> state_initialize_decoder_result : completion_initialize_run_ [guard_encoder_initialize_succeeded_] / effect_initialize_decoder_ + state_initialize_encoder_result --> state_failed : completion_initialize_run_ [guard_encoder_initialize_failed_] / codec_initialize_failed__ + state_initialize_decoder_result --> state_initialize_executor_result : completion_initialize_run_ [initialize_run__] / effect_initialize_executor_ + state_initialize_decoder_result --> state_failed : completion_initialize_run_ [initialize_run__] / codec_initialize_failed__ + state_initialize_executor_result --> state_initialize_generator_result : completion_initialize_run_ [initialize_run__] / effect_initialize_generator_ + state_initialize_executor_result --> state_failed : completion_initialize_run_ [initialize_run__] / executor_initialize_failed__ + state_initialize_generator_result --> state_load_voice_result : completion_initialize_run_ [initialize_run__] / effect_load_voice_ + state_initialize_generator_result --> state_failed : completion_initialize_run_ [initialize_run__] / generator_initialize_failed__ + state_load_voice_result --> state_voice_prefill : completion_initialize_run_ [initialize_run__] / effect_publish_initialize_done_ + state_load_voice_result --> state_failed : completion_initialize_run_ [initialize_run__] / voice_load_failed__ + state_voice_prefill --> state_voice_prefill_result : advance_voice_run [always] / effect_prefill_voice_ + state_voice_prefill_result --> state_voice_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ + state_voice_prefill_result --> state_prompt_begin_result : completion_advance_voice_run_ [advance_voice_run__] / effect_begin_prompt_ + state_voice_prefill_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / voice_prefill_failed__ + state_prompt_begin_result --> state_prompt_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ + state_prompt_begin_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / prompt_begin_failed__ + state_prompt_prefill --> state_prompt_prefill_result : advance_prompt_run [always] / effect_prefill_prompt_ + state_prompt_prefill_result --> state_prompt_prefill : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ + state_prompt_prefill_result --> state_live : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ + state_prompt_prefill_result --> state_failed : completion_advance_prompt_run_ [advance_prompt_run__] / prompt_prefill_failed__ + state_live --> state_live_encode_result : live_frame_run [live_frame_run__] / live_frame_run__ + state_live --> state_failed : live_frame_run [live_frame_run__] / invalid_request__ + state_live_encode_result --> state_live_generate_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_encode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / encode_failed__ + state_live_generate_result --> state_live_decode_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_generate_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_generate_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / generate_failed__ + state_live_decode_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_decode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / decode_failed__ + state_live --> state_flush : begin_flush_run [always] / effect_publish_begin_flush_done_ + state_flush --> state_flush_encode_result : flush_frame_run [flush_frame_run__] / flush_frame_run__ + state_flush --> state_failed : flush_frame_run [flush_frame_run__] / invalid_request__ + state_flush_encode_result --> state_flush_generate_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_encode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / encode_failed__ + state_flush_generate_result --> state_flush_decode_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_generate_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_generate_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / generate_failed__ + state_flush_decode_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_decode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / decode_failed__ + state_flush --> state_done : finish_run [always] / effect_publish_finish_done_ + state_uninitialized --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_temporal_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_depformer_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_encoder_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_decoder_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_executor_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_generator_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_load_voice_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_voice_prefill --> state_failed : _ [always] / effect_mark_unexpected_ + state_voice_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_prompt_begin_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_prompt_prefill --> state_failed : _ [always] / effect_mark_unexpected_ + state_prompt_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_live --> state_failed : _ [always] / effect_mark_unexpected_ + state_live_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_live_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_live_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_done --> state_failed : _ [always] / effect_mark_unexpected_ + state_failed --> state_failed : _ [always] / effect_mark_unexpected_ diff --git a/.planning/architecture/speech_generator_moshi.md b/.planning/architecture/speech_generator_moshi.md new file mode 100644 index 00000000..04a1778b --- /dev/null +++ b/.planning/architecture/speech_generator_moshi.md @@ -0,0 +1,400 @@ +# speech_generator_moshi + +Source: [`emel/speech/generator/moshi/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) + +## Mermaid + +```mermaid +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none + state_bind_contract_decision --> state_binding : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ + state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ + state_binding --> state_lmgen_mode_decision : completion_initialize_run_ [always] / none + state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_personaplex_lmgen_] / effect_configure_personaplex_lmgen_ + state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_standard_lmgen_] / effect_configure_standard_lmgen_ + state_configure_lmgen --> state_reserve_memory : completion_initialize_run_ [always] / effect_reserve_memory_ + state_reserve_memory --> state_reserve_memory_decision : completion_initialize_run_ [always] / none + state_reserve_memory_decision --> state_allocate_sequence : completion_initialize_run_ [guard_memory_accepted_] / effect_allocate_sequence_ + state_reserve_memory_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ + state_allocate_sequence --> state_allocate_sequence_decision : completion_initialize_run_ [always] / none + state_allocate_sequence_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_memory_accepted_] / none + state_allocate_sequence_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_done_ + state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / none + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / none + state_session_ready --> state_voice_request_decision : load_voice_run [always] / none + state_voice_request_decision --> state_voice_error_out_decision : completion_load_voice_run_ [guard_voice_contract_valid_] / effect_bind_voice_contract_ + state_voice_request_decision --> state_voice_failed_error_out_decision : completion_load_voice_run_ [guard_voice_contract_invalid_] / load_voice_run__ + state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ + state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none + state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ + state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / none + state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_done_ + state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none + state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ + state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none + state_session_ready --> state_prefill_voice_request_decision : prefill_voice_run [always] / none + state_prefill_voice_request_decision --> state_prefill_voice_allocate_slot : completion_prefill_voice_run_ [guard_voice_prefill_request_valid_] / effect_allocate_voice_prefill_slot_ + state_prefill_voice_request_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_prefill_request_invalid_] / prefill_voice_run__ + state_prefill_voice_allocate_slot --> state_prefill_voice_allocate_slot_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_allocate_slot_decision --> state_prefill_voice_capture_memory : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_capture_voice_prefill_memory_ + state_prefill_voice_allocate_slot_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ + state_prefill_voice_capture_memory --> state_prefill_voice_capture_memory_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_capture_memory_decision --> state_prefill_voice_begin : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_begin_voice_prefill_ + state_prefill_voice_capture_memory_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ + state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f32_] / effect_load_voice_embedding_frame_f32_ + state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f16_] / effect_load_voice_embedding_frame_f16_ + state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_bf16_] / effect_load_voice_embedding_frame_bf16_ + state_prefill_voice_embedding_frame --> state_prefill_voice_embedding_frame_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_embedding_frame_decision --> state_prefill_voice_graph_runtime_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_loaded_] / none + state_prefill_voice_embedding_frame_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_failed_] / prefill_voice_run__ + state_prefill_voice_graph_runtime_decision --> state_prefill_voice_running_graph : completion_prefill_voice_run_ [guard_graph_runtime_available_] / effect_run_voice_graph_runtime_ + state_prefill_voice_graph_runtime_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_runtime_unavailable_] / prefill_voice_run__ + state_prefill_voice_running_graph --> state_prefill_voice_graph_error_out_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ + state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_no_graph_error_out_] / none + state_prefill_voice_graph_result_decision --> state_prefill_voice_advance : completion_prefill_voice_run_ [guard_graph_step_accepted_] / effect_advance_voice_prefill_ + state_prefill_voice_graph_result_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_step_rejected_] / prefill_voice_run__ + state_prefill_voice_advance --> state_prefill_voice_complete_decision : completion_prefill_voice_run_ [always] / none + state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_complete_] / effect_copy_voice_cache_ + state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_pending_] / none + state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_has_voice_complete_out_] / effect_store_voice_complete_out_ + state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_no_voice_complete_out_] / none + state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_has_voice_remaining_out_] / effect_store_voice_remaining_out_ + state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_no_voice_remaining_out_] / none + state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ + state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ + state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_done_ + state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ + state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_session_ready --> state_personaplex_prompt_begin_decision : begin_personaplex_prompt_run [always] / none + state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_nonempty_valid_] / effect_bind_personaplex_prompt_ + state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_empty_valid_] / effect_bind_empty_personaplex_prompt_ + state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_failed_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_invalid_] / begin_personaplex_prompt_run__ + state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ + state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ + state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_done_ + state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ + state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_session_ready --> state_prefill_personaplex_prompt_request_decision : prefill_personaplex_prompt_run [always] / none + state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_allocate_slot : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_valid_] / effect_allocate_personaplex_prompt_slot_ + state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_invalid_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_allocate_slot --> state_prefill_personaplex_prompt_allocate_slot_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_capture_memory : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_capture_personaplex_prompt_memory_ + state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_capture_memory --> state_prefill_personaplex_prompt_capture_memory_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_begin : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_begin_personaplex_prompt_prefill_ + state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_begin --> state_prefill_personaplex_prompt_phase_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pre_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_text_pending_] / effect_build_personaplex_prompt_text_frame_ + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_post_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ + state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_phase_invalid_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_frame --> state_prefill_personaplex_prompt_write_input : completion_prefill_personaplex_prompt_run_ [always] / effect_write_and_build_personaplex_prompt_input_ + state_prefill_personaplex_prompt_write_input --> state_prefill_personaplex_prompt_graph_runtime_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_running_graph : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_available_] / effect_run_personaplex_prompt_graph_runtime_ + state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_unavailable_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_running_graph --> state_prefill_personaplex_prompt_graph_error_out_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ + state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_no_graph_error_out_] / none + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_pre_silence_] / effect_advance_personaplex_prompt_pre_silence_ + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_text_] / effect_advance_personaplex_prompt_text_ + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_post_silence_] / effect_advance_personaplex_prompt_post_silence_ + state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_step_rejected_] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_advance --> state_prefill_personaplex_prompt_complete_decision : completion_prefill_personaplex_prompt_run_ [always] / none + state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_complete_] / effect_finish_personaplex_prompt_ + state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pending_] / effect_publish_personaplex_prompt_pending_ + state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_complete_out_] / effect_store_personaplex_prompt_complete_out_ + state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_complete_out_] / none + state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_remaining_out_] / effect_store_personaplex_prompt_remaining_out_ + state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_remaining_out_] / none + state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ + state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_done_ + state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ + state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_session_ready --> state_step_request_decision : step_run [always] / none + state_step_request_decision --> state_allocate_step_slot : completion_step_run_ [guard_step_request_valid_] / effect_allocate_step_slot_ + state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_blocked_by_voice_prompt_] / effect_mark_voice_prompt_pending_ + state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_request_shape_invalid_] / effect_mark_step_request_invalid_ + state_allocate_step_slot --> state_allocate_step_slot_decision : completion_step_run_ [always] / none + state_allocate_step_slot_decision --> state_capture_memory : completion_step_run_ [guard_memory_accepted_] / effect_capture_memory_ + state_allocate_step_slot_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ + state_capture_memory --> state_capture_memory_decision : completion_step_run_ [always] / none + state_capture_memory_decision --> state_step_begin : completion_step_run_ [guard_memory_accepted_] / effect_begin_step_ + state_capture_memory_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ + state_step_begin --> state_input_write_decision : completion_step_run_ [always] / none + state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_full_input_] / effect_write_full_input_ + state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_tail_input_] / effect_write_tail_input_ + state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_no_input_write_] / none + state_build_input_sequence --> state_graph_runtime_decision : completion_step_run_ [always] / effect_build_input_sequence_ + state_graph_runtime_decision --> state_running_graph : completion_step_run_ [guard_graph_runtime_available_] / effect_run_graph_runtime_ + state_graph_runtime_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_runtime_unavailable_] / step_run__ + state_running_graph --> state_graph_error_out_decision : completion_step_run_ [always] / none + state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ + state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_no_graph_error_out_] / none + state_graph_result_decision --> state_depformer_decision : completion_step_run_ [guard_graph_step_accepted_] / none + state_graph_result_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_step_rejected_] / step_run__ + state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_replace_depformer_tokens_] / effect_replace_audio_with_zero_ + state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_use_graph_audio_tokens_] / none + state_apply_delay_mask --> state_write_generated_decision : completion_step_run_ [always] / effect_apply_delay_mask_and_advance_ + state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_should_write_generated_] / effect_write_generated_ + state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_provided_input_] / effect_write_generated_missing_ + state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_skip_pending_] / effect_consume_skip_ + state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_before_delay_] / effect_publish_no_output_ + state_skip_delay_decision --> state_collect_output : completion_step_run_ [guard_past_delay_] / effect_collect_delayed_output_ + state_collect_output --> state_output_decision : completion_step_run_ [always] / none + state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_has_ungenerated_] / effect_publish_no_output_ + state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_complete_] / effect_publish_output_ + state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_has_produced_out_] / effect_store_produced_out_ + state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_no_produced_out_] / none + state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / step_run__ + state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / none + state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / step_run__ + state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / none + state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_done_ + state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none + state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_error_ + state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none + state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / step_run__ + state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / step_run__ + state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / none + state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / effect_emit_step_error_ + state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / none + state_uninitialized --> state_uninit_voice_error_out_decision : load_voice_run [always] / load_voice_run__ + state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ + state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none + state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ + state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / none + state_uninitialized --> state_uninit_prefill_voice_error_out_decision : prefill_voice_run [always] / prefill_voice_run__ + state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ + state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ + state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / none + state_uninitialized --> state_uninit_begin_personaplex_prompt_error_out_decision : begin_personaplex_prompt_run [always] / begin_personaplex_prompt_run__ + state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ + state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ + state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none + state_uninitialized --> state_uninit_prefill_personaplex_prompt_error_out_decision : prefill_personaplex_prompt_run [always] / prefill_personaplex_prompt_run__ + state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ + state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ + state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none + state_session_ready --> state_uninitialized : reset_run [always] / effect_reset_session_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ +``` + +## Transitions + +| Source | Event | Guard | Action | Target | +| --- | --- | --- | --- | --- | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_configure_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_configure_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_reserve_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_voice_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_load_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_voice_prefill_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_capture_voice_prefill_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_begin_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_loaded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_run_voice_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_copy_voice_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_nonempty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_empty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_empty_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_personaplex_prompt_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_capture_personaplex_prompt_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_begin_personaplex_prompt_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_pre_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_text_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_personaplex_prompt_text_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_post_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_phase_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_and_build_personaplex_prompt_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_run_personaplex_prompt_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_finish_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_step_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_step_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_step_blocked_by_voice_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_voice_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_step_request_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_step_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_capture_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_begin_step>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_no_input_write>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_input_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_run_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_replace_depformer_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_replace_audio_with_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_use_graph_audio_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_apply_delay_mask_and_advance>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_should_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_provided_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_generated_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_skip_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_consume_skip>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_before_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_past_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_collect_delayed_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_output_has_ungenerated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_output_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_step_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`reset_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | diff --git a/.planning/architecture/speech_generator_moshi_executor.md b/.planning/architecture/speech_generator_moshi_executor.md new file mode 100644 index 00000000..b38ef744 --- /dev/null +++ b/.planning/architecture/speech_generator_moshi_executor.md @@ -0,0 +1,586 @@ +# speech_generator_moshi_executor + +Source: [`emel/speech/generator/moshi/executor/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) + +## Mermaid + +```mermaid +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none + state_bind_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ + state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ + state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ + state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ + state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ + state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_exceeds_card_] / effect_bind_full_card_text_sampling_top_k_ + state_audio_sampling_top_k_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_audio_sampling_top_k_within_card_] / effect_bind_requested_audio_sampling_top_k_ + state_audio_sampling_top_k_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_audio_sampling_top_k_exceeds_card_] / effect_bind_full_card_audio_sampling_top_k_ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ + state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / none + state_init_callback_decision --> state_ready : completion_initialize_run_ [guard_has_initialize_done_callback_] / effect_emit_initialize_done_ + state_init_callback_decision --> state_ready : completion_initialize_run_ [guard_no_initialize_done_callback_] / none + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [guard_has_initialize_error_callback_] / effect_emit_initialize_error_ + state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [guard_no_initialize_error_callback_] / none + state_ready --> state_step_model_decision : step_run [always] / none + state_step_model_decision --> state_step_shape_decision : completion_step_run_ [guard_step_model_matches_] / none + state_step_model_decision --> state_step_error_out_decision : completion_step_run_ [guard_step_model_mismatch_] / effect_mark_model_mismatch_ + state_step_shape_decision --> state_step_execution_decision : completion_step_run_ [guard_step_shape_valid_] / none + state_step_shape_decision --> state_step_error_out_decision : completion_step_run_ [guard_step_shape_invalid_] / effect_mark_request_shape_ + state_step_execution_decision --> state_input_embedding : completion_step_run_ [guard_input_embedding_supported_] / effect_begin_input_embedding_ + state_step_execution_decision --> state_step_error_out_decision : completion_step_run_ [guard_input_embedding_unsupported_] / effect_mark_graph_execution_unsupported_ + state_input_embedding --> state_input_embedding_result_decision : completion_step_run_ [guard_external_input_embedding_supported_] / effect_apply_external_input_embedding_ + state_input_embedding --> state_input_text_embedding_bind : completion_step_run_ [guard_token_input_embedding_supported_] / effect_bind_input_text_embedding_ + state_input_embedding --> state_step_error_out_decision : completion_step_run_ [guard_token_input_embedding_unsupported_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_bind --> state_input_text_embedding_bind_result_decision : completion_step_run_ [always] / none + state_input_text_embedding_bind_result_decision --> state_input_text_embedding_row : completion_step_run_ [guard_embedding_view_bound_] / effect_run_embedding_row_fetch_ + state_input_text_embedding_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_row --> state_input_text_embedding_row_result_decision : completion_step_run_ [always] / none + state_input_text_embedding_row_result_decision --> state_input_text_embedding_apply : completion_step_run_ [guard_embedding_row_succeeded_] / effect_apply_input_text_embedding_row_ + state_input_text_embedding_row_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_row_failed_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_apply --> state_input_text_embedding_result_decision : completion_step_run_ [guard_input_text_embedding_succeeded_] / none + state_input_text_embedding_apply --> state_step_error_out_decision : completion_step_run_ [guard_input_text_embedding_failed_] / effect_mark_graph_execution_unsupported_ + state_input_text_embedding_result_decision --> state_input_audio_token_decision : completion_step_run_ [always] / none + state_input_audio_token_decision --> state_input_audio_embedding : completion_step_run_ [guard_current_input_audio_token_present_] / effect_bind_input_audio_embedding_ + state_input_audio_token_decision --> state_input_audio_embedding_result_decision : completion_step_run_ [guard_current_input_audio_token_zero_] / effect_skip_zero_input_audio_embedding_ + state_input_audio_token_decision --> state_step_error_out_decision : completion_step_run_ [guard_current_input_audio_token_unsupported_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding --> state_input_audio_embedding_bind_result_decision : completion_step_run_ [always] / none + state_input_audio_embedding_bind_result_decision --> state_input_audio_embedding_row : completion_step_run_ [guard_embedding_view_bound_] / effect_run_embedding_row_fetch_ + state_input_audio_embedding_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding_row --> state_input_audio_embedding_row_result_decision : completion_step_run_ [always] / none + state_input_audio_embedding_row_result_decision --> state_input_audio_embedding_apply : completion_step_run_ [guard_embedding_row_succeeded_] / effect_apply_input_audio_embedding_row_ + state_input_audio_embedding_row_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_row_failed_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding_apply --> state_input_audio_embedding_result_decision : completion_step_run_ [guard_input_audio_embedding_succeeded_] / none + state_input_audio_embedding_apply --> state_step_error_out_decision : completion_step_run_ [guard_input_audio_embedding_failed_] / effect_mark_graph_execution_unsupported_ + state_input_audio_embedding_result_decision --> state_input_audio_codebook_advance : completion_step_run_ [guard_more_input_audio_codebooks_] / effect_advance_input_audio_codebook_ + state_input_audio_codebook_advance --> state_input_audio_token_decision : completion_step_run_ [always] / none + state_input_audio_embedding_result_decision --> state_input_embedding_result_decision : completion_step_run_ [guard_input_audio_codebooks_complete_] / effect_finish_input_embedding_ + state_input_embedding_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_input_embedding_failed_] / effect_mark_graph_execution_unsupported_ + state_input_embedding_result_decision --> state_bind_temporal_kv : completion_step_run_ [guard_temporal_kv_binding_present_] / effect_bind_temporal_kv_ + state_input_embedding_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_kv_binding_missing_] / effect_mark_graph_execution_unsupported_ + state_bind_temporal_kv --> state_temporal_kv_result_decision : completion_step_run_ [guard_temporal_kv_bound_] / none + state_bind_temporal_kv --> state_step_error_out_decision : completion_step_run_ [guard_temporal_kv_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_kv_result_decision --> state_temporal_position_result_decision : completion_step_run_ [always] / effect_advance_temporal_position_ + state_temporal_position_result_decision --> state_temporal_position_valid_decision : completion_step_run_ [guard_temporal_position_advance_succeeded_] / none + state_temporal_position_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_position_advance_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_position_valid_decision --> state_temporal_layer_norm : completion_step_run_ [guard_temporal_layer_norm_supported_] / effect_run_temporal_layer_norm_rms_ + state_temporal_position_valid_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm --> state_temporal_layer_norm_rms_result_decision : completion_step_run_ [always] / none + state_temporal_layer_norm_rms_result_decision --> state_temporal_layer_norm_scale : completion_step_run_ [guard_temporal_layer_norm_rms_succeeded_] / effect_run_temporal_layer_norm_scale_ + state_temporal_layer_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm_scale --> state_temporal_layer_norm_result_decision : completion_step_run_ [guard_temporal_layer_norm_succeeded_] / none + state_temporal_layer_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm_result_decision --> state_temporal_layer_projection : completion_step_run_ [guard_temporal_layer_projection_supported_] / effect_bind_temporal_layer_projection_ + state_temporal_layer_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_projection --> state_temporal_layer_projection_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_projection_bind_result_decision --> state_temporal_layer_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_projection_ + state_temporal_layer_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_projection_run --> state_temporal_layer_projection_result_decision : completion_step_run_ [guard_temporal_layer_projection_succeeded_] / none + state_temporal_layer_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_projection_result_decision --> state_temporal_layer_rope : completion_step_run_ [guard_temporal_layer_rope_supported_] / effect_run_temporal_layer_rope_0__ + state_temporal_layer_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_rope_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_rope --> state_temporal_layer_rope_result_decision : completion_step_run_ [guard_temporal_layer_rope_succeeded_] / effect_copy_temporal_layer_rope_0__ + state_temporal_layer_rope --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_rope_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_rope_result_decision --> state_temporal_layer_key_rope : completion_step_run_ [always] / effect_run_temporal_layer_rope_1__ + state_temporal_layer_key_rope --> state_temporal_layer_key_rope_result_decision : completion_step_run_ [guard_temporal_layer_rope_succeeded_] / effect_copy_temporal_layer_rope_1__ + state_temporal_layer_key_rope --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_rope_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_key_rope_result_decision --> state_temporal_layer_cache_write : completion_step_run_ [guard_temporal_layer_cache_write_supported_] / effect_write_temporal_layer_kv_cache_ + state_temporal_layer_key_rope_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_cache_write_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_cache_write --> state_temporal_layer_cache_write_result_decision : completion_step_run_ [guard_temporal_layer_cache_write_succeeded_] / none + state_temporal_layer_cache_write --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_cache_write_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_cache_write_result_decision --> state_temporal_layer_attention : completion_step_run_ [guard_temporal_layer_attention_supported_] / effect_run_temporal_layer_attention_ + state_temporal_layer_cache_write_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_attention_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_attention --> state_temporal_layer_attention_result_decision : completion_step_run_ [guard_temporal_layer_attention_succeeded_] / none + state_temporal_layer_attention --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_attention_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_attention_result_decision --> state_temporal_layer_out_projection : completion_step_run_ [guard_temporal_layer_out_projection_supported_] / effect_bind_temporal_layer_out_projection_ + state_temporal_layer_attention_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_out_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_out_projection --> state_temporal_layer_out_projection_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_out_projection_bind_result_decision --> state_temporal_layer_out_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_out_projection_ + state_temporal_layer_out_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_out_projection_run --> state_temporal_layer_out_projection_result_decision : completion_step_run_ [guard_temporal_layer_out_projection_succeeded_] / none + state_temporal_layer_out_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_out_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_out_projection_result_decision --> state_temporal_layer_residual : completion_step_run_ [always] / effect_apply_temporal_layer_attention_residual_ + state_temporal_layer_residual --> state_temporal_layer_residual_result_decision : completion_step_run_ [guard_temporal_layer_residual_succeeded_] / none + state_temporal_layer_residual --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_residual_result_decision --> state_temporal_layer_norm2 : completion_step_run_ [guard_temporal_layer_norm2_supported_] / effect_run_temporal_layer_norm2_rms_ + state_temporal_layer_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm2_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm2 --> state_temporal_layer_norm2_rms_result_decision : completion_step_run_ [always] / none + state_temporal_layer_norm2_rms_result_decision --> state_temporal_layer_norm2_scale : completion_step_run_ [guard_temporal_layer_norm2_rms_succeeded_] / effect_run_temporal_layer_norm2_scale_ + state_temporal_layer_norm2_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm2_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm2_scale --> state_temporal_layer_norm2_result_decision : completion_step_run_ [guard_temporal_layer_norm2_succeeded_] / none + state_temporal_layer_norm2_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm2_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_norm2_result_decision --> state_temporal_layer_gating_in : completion_step_run_ [guard_temporal_layer_gating_in_supported_] / effect_bind_temporal_layer_gating_in_ + state_temporal_layer_norm2_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_in_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_in --> state_temporal_layer_gating_in_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_gating_in_bind_result_decision --> state_temporal_layer_gating_in_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_gating_in_ + state_temporal_layer_gating_in_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_in_run --> state_temporal_layer_gating_in_result_decision : completion_step_run_ [guard_temporal_layer_gating_in_succeeded_] / none + state_temporal_layer_gating_in_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_in_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_in_result_decision --> state_temporal_layer_silu_gate : completion_step_run_ [guard_temporal_layer_silu_gate_supported_] / effect_run_temporal_layer_silu_gate_silu_ + state_temporal_layer_gating_in_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_silu_gate_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_silu_gate --> state_temporal_layer_silu_gate_silu_result_decision : completion_step_run_ [always] / none + state_temporal_layer_silu_gate_silu_result_decision --> state_temporal_layer_silu_gate_mul : completion_step_run_ [guard_temporal_layer_silu_gate_silu_succeeded_] / effect_run_temporal_layer_silu_gate_mul_ + state_temporal_layer_silu_gate_silu_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_silu_gate_silu_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_silu_gate_mul --> state_temporal_layer_silu_gate_result_decision : completion_step_run_ [guard_temporal_layer_silu_gate_succeeded_] / none + state_temporal_layer_silu_gate_mul --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_silu_gate_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_silu_gate_result_decision --> state_temporal_layer_gating_out : completion_step_run_ [guard_temporal_layer_gating_out_supported_] / effect_bind_temporal_layer_gating_out_ + state_temporal_layer_silu_gate_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_out_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_out --> state_temporal_layer_gating_out_bind_result_decision : completion_step_run_ [always] / none + state_temporal_layer_gating_out_bind_result_decision --> state_temporal_layer_gating_out_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_temporal_layer_gating_out_ + state_temporal_layer_gating_out_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_out_run --> state_temporal_layer_gating_out_result_decision : completion_step_run_ [guard_temporal_layer_gating_out_succeeded_] / none + state_temporal_layer_gating_out_run --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_gating_out_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_gating_out_result_decision --> state_temporal_layer_ff_residual : completion_step_run_ [always] / effect_apply_temporal_layer_ff_residual_ + state_temporal_layer_ff_residual --> state_temporal_layer_ff_residual_result_decision : completion_step_run_ [guard_temporal_layer_ff_residual_succeeded_] / none + state_temporal_layer_ff_residual --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_ff_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_ff_residual_result_decision --> state_temporal_layer_advance : completion_step_run_ [guard_more_temporal_layers_] / effect_advance_temporal_layer_ + state_temporal_layer_ff_residual_result_decision --> state_temporal_out_norm : completion_step_run_ [guard_temporal_layers_complete_] / effect_run_temporal_out_norm_rms_ + state_temporal_layer_ff_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_layer_advance --> state_temporal_layer_norm : completion_step_run_ [guard_temporal_layer_norm_supported_] / effect_run_temporal_layer_norm_rms_ + state_temporal_layer_advance --> state_step_error_out_decision : completion_step_run_ [guard_temporal_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm --> state_temporal_out_norm_rms_result_decision : completion_step_run_ [always] / none + state_temporal_out_norm_rms_result_decision --> state_temporal_out_norm_scale : completion_step_run_ [guard_temporal_out_norm_rms_succeeded_] / effect_run_temporal_out_norm_scale_ + state_temporal_out_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm_scale --> state_temporal_out_norm_result_decision : completion_step_run_ [guard_temporal_out_norm_succeeded_] / effect_publish_temporal_out_norm_ + state_temporal_out_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_failed_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm_result_decision --> state_text_logits : completion_step_run_ [guard_text_logits_supported_] / effect_bind_text_token_logits_ + state_temporal_out_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_text_logits --> state_text_logits_bind_result_decision : completion_step_run_ [always] / none + state_text_logits_bind_result_decision --> state_text_logits_sample_projection : completion_step_run_ [guard_forced_text_token_valid_and_sampling_consume_] / effect_compute_text_token_logits_ + state_text_logits_bind_result_decision --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_token_valid_without_sampling_consume_] / effect_publish_forced_text_token_ + state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_forced_text_sampling_config_invalid_] / effect_mark_graph_execution_unsupported_ + state_text_logits_bind_result_decision --> state_text_logits_run : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_argmax_] / effect_select_text_token_ + state_text_logits_bind_result_decision --> state_text_logits_sample_projection : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_sampling_] / effect_compute_text_token_logits_ + state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid_] / effect_mark_graph_execution_unsupported_ + state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_sample_projection --> state_text_logits_sample_projection_result_decision : completion_step_run_ [always] / none + state_text_logits_sample_projection_result_decision --> state_text_logits_sample_scale : completion_step_run_ [guard_text_logits_matmul_succeeded_] / effect_scale_text_sampling_logits_ + state_text_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_sample_scale --> state_text_logits_sample_softmax : completion_step_run_ [always] / effect_compute_text_sampling_probabilities_ + state_text_logits_sample_softmax --> state_text_logits_sample_top_k : completion_step_run_ [always] / effect_compute_text_sampling_top_k_ + state_text_logits_sample_top_k --> state_text_logits_sample_select : completion_step_run_ [always] / effect_select_text_sampling_token_ + state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_sampled_text_token_ready_] / effect_publish_sampled_text_token_ + state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_sampling_consumed_] / effect_publish_forced_text_token_ + state_text_logits_sample_select --> state_step_error_out_decision : completion_step_run_ [guard_text_sampling_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_run --> state_text_logits_result_decision : completion_step_run_ [guard_text_logits_succeeded_] / none + state_text_logits_run --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_failed_] / effect_mark_graph_execution_unsupported_ + state_text_logits_result_decision --> state_bind_depformer_kv : completion_step_run_ [guard_depformer_kv_binding_present_] / effect_bind_depformer_kv_ + state_text_logits_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_kv_binding_missing_] / effect_mark_graph_execution_unsupported_ + state_bind_depformer_kv --> state_depformer_kv_result_decision : completion_step_run_ [guard_depformer_kv_bound_] / effect_reset_depformer_positions_ + state_bind_depformer_kv --> state_step_error_out_decision : completion_step_run_ [guard_depformer_kv_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_kv_result_decision --> state_depformer_position_reset_result_decision : completion_step_run_ [always] / none + state_depformer_position_reset_result_decision --> state_depformer_position_advance_result_decision : completion_step_run_ [guard_depformer_position_reset_succeeded_] / effect_advance_depformer_position_ + state_depformer_position_reset_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_position_reset_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_position_advance_result_decision --> state_depformer_weight_route_decision : completion_step_run_ [guard_depformer_position_advance_succeeded_] / none + state_depformer_position_advance_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_position_advance_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_weight_route_decision --> state_depformer_weight_decision : completion_step_run_ [guard_depformer_scheduled_weight_present_] / effect_use_depformer_scheduled_weight_ + state_depformer_weight_route_decision --> state_depformer_weight_decision : completion_step_run_ [guard_depformer_scheduled_weight_absent_] / effect_use_depformer_codebook_weight_ + state_depformer_weight_route_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_scheduled_weight_invalid_] / effect_mark_graph_execution_unsupported_ + state_depformer_weight_decision --> state_depformer_input : completion_step_run_ [guard_depformer_text_input_supported_] / effect_bind_depformer_text_input_projection_ + state_depformer_weight_decision --> state_depformer_input : completion_step_run_ [guard_depformer_audio_input_supported_] / effect_bind_depformer_audio_input_projection_ + state_depformer_weight_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_input --> state_depformer_input_projection_bind_result_decision : completion_step_run_ [always] / none + state_depformer_input_projection_bind_result_decision --> state_depformer_input_projection : completion_step_run_ [guard_depformer_input_projection_bound_] / effect_run_depformer_input_projection_ + state_depformer_input_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_projection_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_projection --> state_depformer_input_projection_result_decision : completion_step_run_ [always] / none + state_depformer_input_projection_result_decision --> state_depformer_input_embedding_bind : completion_step_run_ [guard_depformer_text_input_projection_succeeded_] / effect_bind_depformer_text_input_embedding_ + state_depformer_input_projection_result_decision --> state_depformer_input_embedding_bind : completion_step_run_ [guard_depformer_audio_input_projection_succeeded_] / effect_bind_depformer_audio_input_embedding_ + state_depformer_input_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_projection_embedding_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_embedding_bind --> state_depformer_input_embedding_bind_result_decision : completion_step_run_ [always] / none + state_depformer_input_embedding_bind_result_decision --> state_depformer_input_embedding_row : completion_step_run_ [guard_embedding_view_bound_] / effect_run_embedding_row_fetch_ + state_depformer_input_embedding_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_embedding_row --> state_depformer_input_embedding_row_result_decision : completion_step_run_ [always] / none + state_depformer_input_embedding_row_result_decision --> state_depformer_input_embedding_apply : completion_step_run_ [guard_embedding_row_succeeded_] / effect_apply_depformer_input_embedding_row_ + state_depformer_input_embedding_row_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_embedding_row_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_embedding_apply --> state_depformer_input_result_decision : completion_step_run_ [guard_depformer_input_succeeded_] / none + state_depformer_input_embedding_apply --> state_step_error_out_decision : completion_step_run_ [guard_depformer_input_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_input_result_decision --> state_depformer_layer_norm : completion_step_run_ [guard_depformer_layer_norm_supported_] / effect_run_depformer_layer_norm_rms_ + state_depformer_input_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm --> state_depformer_layer_norm_rms_result_decision : completion_step_run_ [always] / none + state_depformer_layer_norm_rms_result_decision --> state_depformer_layer_norm_scale : completion_step_run_ [guard_depformer_layer_norm_rms_succeeded_] / effect_run_depformer_layer_norm_scale_ + state_depformer_layer_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm_scale --> state_depformer_layer_norm_result_decision : completion_step_run_ [guard_depformer_layer_norm_succeeded_] / none + state_depformer_layer_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm_result_decision --> state_depformer_layer_projection : completion_step_run_ [guard_depformer_layer_projection_supported_] / effect_bind_depformer_layer_projection_ + state_depformer_layer_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_projection --> state_depformer_layer_projection_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_projection_bind_result_decision --> state_depformer_layer_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_projection_ + state_depformer_layer_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_projection_run --> state_depformer_layer_projection_result_decision : completion_step_run_ [guard_depformer_layer_projection_succeeded_] / none + state_depformer_layer_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_projection_result_decision --> state_depformer_layer_cache_write : completion_step_run_ [guard_depformer_layer_cache_write_supported_] / effect_write_depformer_layer_kv_cache_ + state_depformer_layer_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_cache_write_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_cache_write --> state_depformer_layer_cache_write_result_decision : completion_step_run_ [guard_depformer_layer_cache_write_succeeded_] / none + state_depformer_layer_cache_write --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_cache_write_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_cache_write_result_decision --> state_depformer_layer_attention : completion_step_run_ [guard_depformer_layer_attention_supported_] / effect_run_depformer_layer_attention_ + state_depformer_layer_cache_write_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_attention_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_attention --> state_depformer_layer_attention_result_decision : completion_step_run_ [guard_depformer_layer_attention_succeeded_] / none + state_depformer_layer_attention --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_attention_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_attention_result_decision --> state_depformer_layer_out_projection : completion_step_run_ [guard_depformer_layer_out_projection_supported_] / effect_bind_depformer_layer_out_projection_ + state_depformer_layer_attention_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_out_projection_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_out_projection --> state_depformer_layer_out_projection_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_out_projection_bind_result_decision --> state_depformer_layer_out_projection_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_out_projection_ + state_depformer_layer_out_projection_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_out_projection_run --> state_depformer_layer_out_projection_result_decision : completion_step_run_ [guard_depformer_layer_out_projection_succeeded_] / none + state_depformer_layer_out_projection_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_out_projection_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_out_projection_result_decision --> state_depformer_layer_residual : completion_step_run_ [always] / effect_apply_depformer_layer_attention_residual_ + state_depformer_layer_residual --> state_depformer_layer_residual_result_decision : completion_step_run_ [guard_depformer_layer_residual_succeeded_] / none + state_depformer_layer_residual --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_residual_result_decision --> state_depformer_layer_norm2 : completion_step_run_ [guard_depformer_layer_norm2_supported_] / effect_run_depformer_layer_norm2_rms_ + state_depformer_layer_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm2_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm2 --> state_depformer_layer_norm2_rms_result_decision : completion_step_run_ [always] / none + state_depformer_layer_norm2_rms_result_decision --> state_depformer_layer_norm2_scale : completion_step_run_ [guard_depformer_layer_norm2_rms_succeeded_] / effect_run_depformer_layer_norm2_scale_ + state_depformer_layer_norm2_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm2_rms_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm2_scale --> state_depformer_layer_norm2_result_decision : completion_step_run_ [guard_depformer_layer_norm2_succeeded_] / none + state_depformer_layer_norm2_scale --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm2_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_norm2_result_decision --> state_depformer_layer_gating_in : completion_step_run_ [guard_depformer_layer_gating_in_supported_] / effect_bind_depformer_layer_gating_in_ + state_depformer_layer_norm2_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_in_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_in --> state_depformer_layer_gating_in_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_gating_in_bind_result_decision --> state_depformer_layer_gating_in_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_gating_in_ + state_depformer_layer_gating_in_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_in_run --> state_depformer_layer_gating_in_result_decision : completion_step_run_ [guard_depformer_layer_gating_in_succeeded_] / none + state_depformer_layer_gating_in_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_in_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_in_result_decision --> state_depformer_layer_silu_gate : completion_step_run_ [guard_depformer_layer_silu_gate_supported_] / effect_run_depformer_layer_silu_gate_silu_ + state_depformer_layer_gating_in_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_silu_gate_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_silu_gate --> state_depformer_layer_silu_gate_silu_result_decision : completion_step_run_ [always] / none + state_depformer_layer_silu_gate_silu_result_decision --> state_depformer_layer_silu_gate_mul : completion_step_run_ [guard_depformer_layer_silu_gate_silu_succeeded_] / effect_run_depformer_layer_silu_gate_mul_ + state_depformer_layer_silu_gate_silu_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_silu_gate_silu_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_silu_gate_mul --> state_depformer_layer_silu_gate_result_decision : completion_step_run_ [guard_depformer_layer_silu_gate_succeeded_] / none + state_depformer_layer_silu_gate_mul --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_silu_gate_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_silu_gate_result_decision --> state_depformer_layer_gating_out : completion_step_run_ [guard_depformer_layer_gating_out_supported_] / effect_bind_depformer_layer_gating_out_ + state_depformer_layer_silu_gate_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_out_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_out --> state_depformer_layer_gating_out_bind_result_decision : completion_step_run_ [always] / none + state_depformer_layer_gating_out_bind_result_decision --> state_depformer_layer_gating_out_run : completion_step_run_ [guard_projection_view_bound_] / effect_run_depformer_layer_gating_out_ + state_depformer_layer_gating_out_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_out_run --> state_depformer_layer_gating_out_result_decision : completion_step_run_ [guard_depformer_layer_gating_out_succeeded_] / none + state_depformer_layer_gating_out_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_gating_out_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_gating_out_result_decision --> state_depformer_layer_ff_residual : completion_step_run_ [always] / effect_apply_depformer_layer_ff_residual_ + state_depformer_layer_ff_residual --> state_depformer_layer_ff_residual_result_decision : completion_step_run_ [guard_depformer_layer_ff_residual_succeeded_] / none + state_depformer_layer_ff_residual --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_ff_residual_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_layer_ff_residual_result_decision --> state_depformer_layer_advance : completion_step_run_ [guard_more_depformer_layers_] / effect_advance_depformer_layer_ + state_depformer_layer_ff_residual_result_decision --> state_depformer_logits : completion_step_run_ [guard_depformer_logits_supported_] / effect_bind_depformer_token_logits_ + state_depformer_layer_ff_residual_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits --> state_depformer_logits_bind_result_decision : completion_step_run_ [always] / none + state_depformer_logits_bind_result_decision --> state_depformer_logits_run : completion_step_run_ [guard_depformer_logits_projection_bound_argmax_] / effect_select_depformer_token_ + state_depformer_logits_bind_result_decision --> state_depformer_logits_sample_projection : completion_step_run_ [guard_depformer_logits_projection_bound_sampling_] / effect_compute_depformer_token_logits_ + state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_projection_bound_sampling_invalid_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_sample_projection --> state_depformer_logits_sample_projection_result_decision : completion_step_run_ [always] / none + state_depformer_logits_sample_projection_result_decision --> state_depformer_logits_sample_scale : completion_step_run_ [guard_depformer_logits_matmul_succeeded_] / effect_scale_depformer_sampling_logits_ + state_depformer_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_sample_scale --> state_depformer_logits_sample_softmax : completion_step_run_ [always] / effect_compute_depformer_sampling_probabilities_ + state_depformer_logits_sample_softmax --> state_depformer_logits_sample_top_k : completion_step_run_ [always] / effect_compute_depformer_sampling_top_k_ + state_depformer_logits_sample_top_k --> state_depformer_logits_sample_select : completion_step_run_ [always] / effect_select_depformer_sampling_token_ + state_depformer_layer_advance --> state_depformer_layer_norm : completion_step_run_ [guard_depformer_layer_norm_supported_] / effect_run_depformer_layer_norm_rms_ + state_depformer_layer_advance --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_run --> state_depformer_token_publish : completion_step_run_ [guard_depformer_logits_succeeded_] / effect_publish_depformer_token_ + state_depformer_logits_run --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_logits_sample_select --> state_depformer_token_publish : completion_step_run_ [guard_depformer_sampling_succeeded_] / effect_publish_depformer_token_ + state_depformer_logits_sample_select --> state_step_error_out_decision : completion_step_run_ [guard_depformer_sampling_failed_] / effect_mark_graph_execution_unsupported_ + state_depformer_token_publish --> state_depformer_logits_result_decision : completion_step_run_ [always] / none + state_depformer_logits_result_decision --> state_depformer_codebook_advance : completion_step_run_ [guard_more_depformer_codebooks_] / effect_advance_depformer_codebook_ + state_depformer_logits_result_decision --> state_ready : completion_step_run_ [guard_depformer_codebooks_complete_] / none + state_depformer_codebook_advance --> state_depformer_position_advance_result_decision : completion_step_run_ [always] / effect_advance_depformer_position_ + state_step_error_out_decision --> state_ready : completion_step_run_ [step_run__] / step_run__ + state_step_error_out_decision --> state_ready : completion_step_run_ [step_run__] / none + state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / effect_mark_not_initialized_ + state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / step_run__ + state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / none + state_ready --> state_uninitialized : reset [always] / effect_reset_session_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ +``` + +## Transitions + +| Source | Event | Guard | Action | Target | +| --- | --- | --- | --- | --- | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_sampling_seed_nonzero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_nonzero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_sampling_seed_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_zero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_requested_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_exceeds_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_full_card_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_audio_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_requested_audio_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_audio_sampling_top_k_exceeds_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_full_card_audio_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_has_initialize_done_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_no_initialize_done_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_has_initialize_error_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_no_initialize_error_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_model_matches>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_model_mismatch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_model_mismatch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_shape_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_request_shape>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_begin_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_external_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_external_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_token_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_input_text_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_token_input_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_input_text_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_text_embedding_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_text_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_input_audio_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_skip_zero_input_audio_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_input_audio_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_audio_embedding_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_audio_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_input_audio_codebooks>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_input_audio_codebook>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_audio_codebooks_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_finish_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_binding_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_kv>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_binding_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_temporal_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_position_advance_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_position_advance_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_rope<0>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_copy_temporal_layer_rope<0>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_rope<1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_copy_temporal_layer_rope<1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_write_temporal_layer_kv_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_attention>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_temporal_layer_attention_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm2_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm2_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_silu_gate_silu>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_silu_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_silu_gate_mul>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_silu_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_temporal_layer_ff_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_ff_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_ff_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_temporal_layers>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_temporal_layer>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layers_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_out_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_out_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_temporal_out_norm>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_and_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_without_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_sampling_config_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_sampling>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_scale_text_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_text_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_sampled_text_token_ready>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_sampled_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_sampling_consumed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_sampling_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_binding_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_kv>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_binding_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_reset_depformer_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_reset_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_reset_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_advance_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_advance_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_use_depformer_scheduled_weight>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_use_depformer_codebook_weight>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_text_input_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_text_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_audio_input_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_audio_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_text_input_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_text_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_audio_input_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_audio_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_depformer_input_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_write_depformer_layer_kv_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_attention>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_depformer_layer_attention_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm2_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm2_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_silu_gate_silu>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_silu_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_silu_gate_mul>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_silu_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_depformer_layer_ff_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_ff_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_ff_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_depformer_layers>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_layer>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_sampling>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_depformer_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_scale_depformer_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_depformer_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_sampling_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_sampling_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_depformer_codebooks>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_codebook>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_codebooks_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_depformer_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_not_initialized>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | diff --git a/.planning/architecture/speech_generator_moshi_personaplex_session.md b/.planning/architecture/speech_generator_moshi_personaplex_session.md new file mode 100644 index 00000000..c6846557 --- /dev/null +++ b/.planning/architecture/speech_generator_moshi_personaplex_session.md @@ -0,0 +1,154 @@ +# speech_generator_moshi_personaplex_session + +Source: [`emel/speech/generator/moshi/personaplex/session/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) + +## Mermaid + +```mermaid +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_initialize_temporal_positions_result : initialize_run [guard_initialize_request_valid_] / effect_initialize_temporal_positions_ + state_initialize_temporal_positions_result --> state_initialize_depformer_positions_result : completion_initialize_run_ [initialize_run__] / effect_initialize_depformer_positions_ + state_initialize_temporal_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ + state_initialize_depformer_positions_result --> state_initialize_encoder_result : completion_initialize_run_ [initialize_run__] / effect_initialize_encoder_ + state_initialize_depformer_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ + state_uninitialized --> state_failed : initialize_run [guard_initialize_request_invalid_] / effect_fail_initialize_invalid_ + state_initialize_encoder_result --> state_initialize_decoder_result : completion_initialize_run_ [guard_encoder_initialize_succeeded_] / effect_initialize_decoder_ + state_initialize_encoder_result --> state_failed : completion_initialize_run_ [guard_encoder_initialize_failed_] / codec_initialize_failed__ + state_initialize_decoder_result --> state_initialize_executor_result : completion_initialize_run_ [initialize_run__] / effect_initialize_executor_ + state_initialize_decoder_result --> state_failed : completion_initialize_run_ [initialize_run__] / codec_initialize_failed__ + state_initialize_executor_result --> state_initialize_generator_result : completion_initialize_run_ [initialize_run__] / effect_initialize_generator_ + state_initialize_executor_result --> state_failed : completion_initialize_run_ [initialize_run__] / executor_initialize_failed__ + state_initialize_generator_result --> state_load_voice_result : completion_initialize_run_ [initialize_run__] / effect_load_voice_ + state_initialize_generator_result --> state_failed : completion_initialize_run_ [initialize_run__] / generator_initialize_failed__ + state_load_voice_result --> state_voice_prefill : completion_initialize_run_ [initialize_run__] / effect_publish_initialize_done_ + state_load_voice_result --> state_failed : completion_initialize_run_ [initialize_run__] / voice_load_failed__ + state_voice_prefill --> state_voice_prefill_result : advance_voice_run [always] / effect_prefill_voice_ + state_voice_prefill_result --> state_voice_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ + state_voice_prefill_result --> state_prompt_begin_result : completion_advance_voice_run_ [advance_voice_run__] / effect_begin_prompt_ + state_voice_prefill_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / voice_prefill_failed__ + state_prompt_begin_result --> state_prompt_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ + state_prompt_begin_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / prompt_begin_failed__ + state_prompt_prefill --> state_prompt_prefill_result : advance_prompt_run [always] / effect_prefill_prompt_ + state_prompt_prefill_result --> state_prompt_prefill : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ + state_prompt_prefill_result --> state_live : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ + state_prompt_prefill_result --> state_failed : completion_advance_prompt_run_ [advance_prompt_run__] / prompt_prefill_failed__ + state_live --> state_live_encode_result : live_frame_run [live_frame_run__] / live_frame_run__ + state_live --> state_failed : live_frame_run [live_frame_run__] / invalid_request__ + state_live_encode_result --> state_live_generate_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_encode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / encode_failed__ + state_live_generate_result --> state_live_decode_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_generate_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_generate_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / generate_failed__ + state_live_decode_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ + state_live_decode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / decode_failed__ + state_live --> state_flush : begin_flush_run [always] / effect_publish_begin_flush_done_ + state_flush --> state_flush_encode_result : flush_frame_run [flush_frame_run__] / flush_frame_run__ + state_flush --> state_failed : flush_frame_run [flush_frame_run__] / invalid_request__ + state_flush_encode_result --> state_flush_generate_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_encode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / encode_failed__ + state_flush_generate_result --> state_flush_decode_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_generate_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_generate_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / generate_failed__ + state_flush_decode_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ + state_flush_decode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / decode_failed__ + state_flush --> state_done : finish_run [always] / effect_publish_finish_done_ + state_uninitialized --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_temporal_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_depformer_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_encoder_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_decoder_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_executor_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_initialize_generator_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_load_voice_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_voice_prefill --> state_failed : _ [always] / effect_mark_unexpected_ + state_voice_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_prompt_begin_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_prompt_prefill --> state_failed : _ [always] / effect_mark_unexpected_ + state_prompt_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_live --> state_failed : _ [always] / effect_mark_unexpected_ + state_live_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_live_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_live_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_flush_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ + state_done --> state_failed : _ [always] / effect_mark_unexpected_ + state_failed --> state_failed : _ [always] / effect_mark_unexpected_ +``` + +## Transitions + +| Source | Event | Guard | Action | Target | +| --- | --- | --- | --- | --- | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_initialize_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_temporal_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_depformer_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`memory_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_encoder>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`memory_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_initialize_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_fail_initialize_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_encoder_initialize_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_decoder>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_encoder_initialize_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`codec_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_executor>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`codec_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_generator>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`executor_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_load_voice>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`generator_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`voice_load_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_prefill_voice>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_begin_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`voice_prefill_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`prompt_begin_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_prefill_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`prompt_prefill_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`encode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`generate_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`decode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`begin_flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_begin_flush_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`encode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`generate_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`decode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`finish_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_finish_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | +| [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | diff --git a/CMakeLists.txt b/CMakeLists.txt index 66f27f7c..801fe4cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,7 @@ if(EMEL_ENABLE_TESTS) tests/speech/codec/mimi_detail_tests.cpp tests/speech/codec/mimi_lifecycle_tests.cpp tests/speech/generator/moshi_lifecycle_tests.cpp + tests/speech/generator/moshi_executor_streaming_tests.cpp tests/speech/generator/moshi_personaplex_session_tests.cpp tests/speech/encoder/whisper/lifecycle_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp diff --git a/README.md b/README.md index c6cf541a..d0bf85e2 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,9 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/speech_codec_mimi.md`](.planning/architecture/speech_codec_mimi.md) - [`.planning/architecture/speech_decoder_whisper.md`](.planning/architecture/speech_decoder_whisper.md) - [`.planning/architecture/speech_encoder_whisper.md`](.planning/architecture/speech_encoder_whisper.md) +- [`.planning/architecture/speech_generator_moshi_executor.md`](.planning/architecture/speech_generator_moshi_executor.md) +- [`.planning/architecture/speech_generator_moshi_personaplex_session.md`](.planning/architecture/speech_generator_moshi_personaplex_session.md) +- [`.planning/architecture/speech_generator_moshi.md`](.planning/architecture/speech_generator_moshi.md) - [`.planning/architecture/tensor_view.md`](.planning/architecture/tensor_view.md) - [`.planning/architecture/text_conditioner.md`](.planning/architecture/text_conditioner.md) - [`.planning/architecture/text_detokenizer.md`](.planning/architecture/text_detokenizer.md) diff --git a/src/emel/speech/generator/moshi/executor/actions.hpp b/src/emel/speech/generator/moshi/executor/actions.hpp index d3485d6d..4abe4ae7 100644 --- a/src/emel/speech/generator/moshi/executor/actions.hpp +++ b/src/emel/speech/generator/moshi/executor/actions.hpp @@ -129,6 +129,10 @@ struct effect_begin_input_embedding { runtime_ev.ctx.embedding_view_bound = false; runtime_ev.ctx.embedding_row_ok = false; runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.temporal_position_accepted = false; + runtime_ev.ctx.temporal_position_error = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.temporal_position = {}; runtime_ev.ctx.depformer_input_projection_bound = false; runtime_ev.ctx.depformer_input_projection_ok = false; runtime_ev.ctx.temporal_layer_norm_rms_ok = false; @@ -151,6 +155,10 @@ struct effect_begin_input_embedding { runtime_ev.ctx.text_logits_ok = false; runtime_ev.ctx.text_sampling_ok = false; runtime_ev.ctx.depformer_kv_bound = false; + runtime_ev.ctx.depformer_position_accepted = false; + runtime_ev.ctx.depformer_position_error = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.depformer_position = {}; runtime_ev.ctx.depformer_input_ok = false; runtime_ev.ctx.depformer_layer_norm_rms_ok = false; runtime_ev.ctx.depformer_layer_norm_ok = false; @@ -172,14 +180,10 @@ struct effect_begin_input_embedding { runtime_ev.ctx.best_score = 0.0f; runtime_ev.ctx.input_audio_codebook_index = 0; runtime_ev.ctx.temporal_layer_index = 0; - runtime_ev.ctx.temporal_logical_position = -1; - runtime_ev.ctx.temporal_physical_position = -1; + runtime_ev.ctx.temporal_rope_position = -1; runtime_ev.ctx.depformer_codebook_index = 0; runtime_ev.ctx.depformer_weight_index = -1; runtime_ev.ctx.depformer_layer_index = 0; - runtime_ev.ctx.depformer_logical_position = -1; - runtime_ev.ctx.depformer_physical_position = -1; - runtime_ev.ctx.depformer_valid_positions = 0; runtime_ev.ctx.embedding_dim = 0; runtime_ev.ctx.embedding_view = {}; runtime_ev.ctx.projection_view = {}; @@ -421,20 +425,11 @@ template struct effect_run_temporal_layer_rope { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; - const auto &snapshot = runtime_ev.request.memory_snapshot; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t head_dim = hidden_dim / lm.num_heads; runtime_ev.ctx.temporal_layer_rope_ok = false; - const size_t sequence = static_cast(runtime_ev.request.sequence_id); - runtime_ev.ctx.temporal_logical_position = - snapshot.sequence_length_values[sequence] - 1; - const size_t logical_block = static_cast( - runtime_ev.ctx.temporal_logical_position / snapshot.block_tokens); - const int32_t block_id = static_cast( - snapshot.sequence_kv_blocks[sequence][logical_block]); - runtime_ev.ctx.temporal_physical_position = - block_id * snapshot.block_tokens + - (runtime_ev.ctx.temporal_logical_position % snapshot.block_tokens); + runtime_ev.ctx.temporal_rope_position = + static_cast(runtime_ev.ctx.temporal_position.logical_position); const uint64_t head_dim_u64 = static_cast(head_dim); const uint64_t heads_u64 = static_cast(lm.num_heads); @@ -454,7 +449,7 @@ template struct effect_run_temporal_layer_rope { }, .src1 = { - .data = &runtime_ev.ctx.temporal_logical_position, + .data = &runtime_ev.ctx.temporal_rope_position, .type = emel::kernel::event::dtype::i32, .ne = {1u, 1u, 1u, 1u}, .nb = {sizeof(int32_t), sizeof(int32_t), sizeof(int32_t), @@ -517,7 +512,7 @@ struct effect_write_temporal_layer_kv_cache { const size_t layer_offset = view.layer_cache_offsets[static_cast( runtime_ev.ctx.temporal_layer_index)]; const size_t physical_position = - static_cast(runtime_ev.ctx.temporal_physical_position); + static_cast(runtime_ev.ctx.temporal_position.physical_position); const size_t dim = static_cast(hidden_dim); const size_t begin = layer_offset + physical_position * dim; const float *key = runtime_ev.ctx.qkv.data() + dim; @@ -536,17 +531,13 @@ struct effect_write_temporal_layer_kv_cache { struct effect_run_temporal_layer_attention { void operator()(const event::step_run &runtime_ev, const context &ctx) const noexcept { - const auto &snapshot = runtime_ev.request.memory_snapshot; const auto &view = runtime_ev.ctx.temporal_kv; + const auto &window = runtime_ev.ctx.temporal_position.window; const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t head_dim = hidden_dim / lm.num_heads; const int32_t capacity = view.position_capacity; - const int32_t sequence_length = - snapshot.sequence_length(runtime_ev.request.sequence_id); - const int32_t current_logical = runtime_ev.ctx.temporal_logical_position; - const int32_t logical_begin = - sequence_length > capacity ? sequence_length - capacity : 0; + const int32_t valid_positions = window.valid_positions; const float scale = 1.0f / std::sqrt(static_cast(head_dim)); const size_t layer_offset = view.layer_cache_offsets[static_cast( runtime_ev.ctx.temporal_layer_index)]; @@ -566,23 +557,19 @@ struct effect_run_temporal_layer_attention { runtime_ev.ctx.attention_scores[static_cast(physical)] = -std::numeric_limits::infinity(); } - for (int32_t logical = logical_begin; logical < sequence_length; - ++logical) { - const int32_t physical = detail::physical_position( - snapshot, runtime_ev.request.sequence_id, logical); - const int32_t delta = current_logical - logical; - const bool visible = - delta >= 0 && (lm.context <= 0 || delta < lm.context); + for (int32_t position = 0; position < valid_positions; ++position) { + const int32_t unwrapped = window.physical_begin + position; + const int32_t physical = + unwrapped - static_cast(unwrapped >= capacity) * capacity; const size_t cache_begin = layer_offset + static_cast(physical) * static_cast(hidden_dim) + static_cast(head_offset); runtime_ev.ctx.attention_scores[static_cast(physical)] = - visible ? emel::kernel::detail::vec_dot_bf16_ggml( - head_dim, view.key_cache.data() + cache_begin, - runtime_ev.ctx.q_bf16.data()) * - scale - : -std::numeric_limits::infinity(); + emel::kernel::detail::vec_dot_bf16_ggml( + head_dim, view.key_cache.data() + cache_begin, + runtime_ev.ctx.q_bf16.data()) * + scale; } emel::kernel::detail::soft_max_row_ggml( @@ -597,10 +584,11 @@ struct effect_run_temporal_layer_attention { runtime_ev.ctx.attention.data() + static_cast(head_offset); for (int32_t dim = 0; dim < head_dim; ++dim) { double sum = 0.0; - for (int32_t logical = logical_begin; logical < sequence_length; - ++logical) { - const int32_t physical = detail::physical_position( - snapshot, runtime_ev.request.sequence_id, logical); + for (int32_t position = 0; position < valid_positions; ++position) { + const int32_t unwrapped = window.physical_begin + position; + const int32_t physical = + unwrapped - + static_cast(unwrapped >= capacity) * capacity; const size_t value_index = layer_offset + static_cast(physical) * static_cast(hidden_dim) + @@ -883,8 +871,6 @@ struct effect_advance_temporal_layer { runtime_ev.ctx.temporal_layer_silu_gate_ok = false; runtime_ev.ctx.temporal_layer_gating_out_ok = false; runtime_ev.ctx.temporal_layer_ff_residual_ok = false; - runtime_ev.ctx.temporal_logical_position = -1; - runtime_ev.ctx.temporal_physical_position = -1; } }; @@ -1055,9 +1041,29 @@ struct effect_bind_depformer_kv { } }; -struct effect_reset_depformer_kv_offset { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - *runtime_ev.ctx.depformer_kv.offset = 0; +struct effect_reset_depformer_positions { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.depformer_position_error = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.depformer_position_accepted = + ctx.depformer_positions->process_event( + emel::memory::streaming::event::reset{ + .error_out = runtime_ev.ctx.depformer_position_error}); + } +}; + +struct effect_advance_depformer_position { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.depformer_position = {}; + runtime_ev.ctx.depformer_position_error = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.depformer_position_accepted = + ctx.depformer_positions->process_event( + emel::memory::streaming::event::advance{ + .result = runtime_ev.ctx.depformer_position, + .error_out = runtime_ev.ctx.depformer_position_error}); } }; @@ -1322,12 +1328,8 @@ struct effect_write_depformer_layer_kv_cache { auto &view = runtime_ev.ctx.depformer_kv; runtime_ev.ctx.depformer_layer_cache_write_ok = false; - const int32_t logical_position = *view.offset; - const int32_t physical_position = logical_position % view.position_capacity; - runtime_ev.ctx.depformer_logical_position = logical_position; - runtime_ev.ctx.depformer_physical_position = physical_position; - runtime_ev.ctx.depformer_valid_positions = - std::min(logical_position + 1, view.position_capacity); + const int32_t physical_position = + runtime_ev.ctx.depformer_position.physical_position; const size_t layer_offset = view.layer_cache_offsets[static_cast( runtime_ev.ctx.depformer_layer_index)]; @@ -1351,11 +1353,12 @@ struct effect_run_depformer_layer_attention { void operator()(const event::step_run &runtime_ev, const context &) const noexcept { const auto &view = runtime_ev.ctx.depformer_kv; + const auto &window = runtime_ev.ctx.depformer_position.window; const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; const int32_t head_dim = dep_dim / lm.depformer_num_heads; const int32_t capacity = view.position_capacity; - const int32_t logical_position = runtime_ev.ctx.depformer_logical_position; + const int32_t valid_positions = window.valid_positions; const float scale = 1.0f / std::sqrt(static_cast(head_dim)); const size_t layer_offset = view.layer_cache_offsets[static_cast( runtime_ev.ctx.depformer_layer_index)]; @@ -1372,18 +1375,22 @@ struct effect_run_depformer_layer_attention { emel::kernel::detail::fp32_to_bf16(q_head[dim]); } for (int32_t physical = 0; physical < capacity; ++physical) { - const bool visible = - logical_position >= capacity || physical <= logical_position; + runtime_ev.ctx.attention_scores[static_cast(physical)] = + -std::numeric_limits::infinity(); + } + for (int32_t position = 0; position < valid_positions; ++position) { + const int32_t unwrapped = window.physical_begin + position; + const int32_t physical = + unwrapped - static_cast(unwrapped >= capacity) * capacity; const size_t cache_begin = layer_offset + static_cast(physical) * static_cast(dep_dim) + static_cast(head_offset); runtime_ev.ctx.attention_scores[static_cast(physical)] = - visible ? emel::kernel::detail::vec_dot_bf16_ggml( - head_dim, view.key_cache.data() + cache_begin, - runtime_ev.ctx.q_bf16.data()) * - scale - : -std::numeric_limits::infinity(); + emel::kernel::detail::vec_dot_bf16_ggml( + head_dim, view.key_cache.data() + cache_begin, + runtime_ev.ctx.q_bf16.data()) * + scale; } emel::kernel::detail::soft_max_row_ggml( @@ -1398,7 +1405,11 @@ struct effect_run_depformer_layer_attention { runtime_ev.ctx.attention.data() + static_cast(head_offset); for (int32_t dim = 0; dim < head_dim; ++dim) { double sum = 0.0; - for (int32_t physical = 0; physical < capacity; ++physical) { + for (int32_t position = 0; position < valid_positions; ++position) { + const int32_t unwrapped = window.physical_begin + position; + const int32_t physical = + unwrapped - + static_cast(unwrapped >= capacity) * capacity; const size_t value_index = layer_offset + static_cast(physical) * static_cast(dep_dim) + @@ -1684,9 +1695,6 @@ struct effect_advance_depformer_layer { runtime_ev.ctx.depformer_layer_silu_gate_ok = false; runtime_ev.ctx.depformer_layer_gating_out_ok = false; runtime_ev.ctx.depformer_layer_ff_residual_ok = false; - runtime_ev.ctx.depformer_logical_position = -1; - runtime_ev.ctx.depformer_physical_position = -1; - runtime_ev.ctx.depformer_valid_positions = 0; } }; @@ -1786,7 +1794,6 @@ struct effect_publish_depformer_token { const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; runtime_ev.request.audio_tokens_out[static_cast(codebook)] = runtime_ev.ctx.best_index; - ++(*runtime_ev.ctx.depformer_kv.offset); } }; @@ -1812,9 +1819,6 @@ struct effect_advance_depformer_codebook { runtime_ev.ctx.depformer_layer_gating_out_ok = false; runtime_ev.ctx.depformer_layer_ff_residual_ok = false; runtime_ev.ctx.depformer_logits_ok = false; - runtime_ev.ctx.depformer_logical_position = -1; - runtime_ev.ctx.depformer_physical_position = -1; - runtime_ev.ctx.depformer_valid_positions = 0; runtime_ev.ctx.depformer_weight_index = -1; } }; @@ -1830,6 +1834,20 @@ struct effect_bind_temporal_kv { } }; +struct effect_advance_temporal_position { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.temporal_position = {}; + runtime_ev.ctx.temporal_position_error = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.temporal_position_accepted = + ctx.temporal_positions->process_event( + emel::memory::streaming::event::advance{ + .result = runtime_ev.ctx.temporal_position, + .error_out = runtime_ev.ctx.temporal_position_error}); + } +}; + template struct effect_store_error_out { void operator()(const runtime_event_type &runtime_ev, context &) const noexcept { diff --git a/src/emel/speech/generator/moshi/executor/any.hpp b/src/emel/speech/generator/moshi/executor/any.hpp index 827d2823..37959433 100644 --- a/src/emel/speech/generator/moshi/executor/any.hpp +++ b/src/emel/speech/generator/moshi/executor/any.hpp @@ -38,6 +38,15 @@ bind_kv_caches(const temporal_kv_binding &temporal, return action::bind_kv_caches(temporal, depformer); } +inline kv_bindings +bind_kv_caches(const temporal_kv_binding &temporal, + const depformer_kv_binding &depformer, + emel::memory::streaming::sm &temporal_positions, + emel::memory::streaming::sm &depformer_positions) noexcept { + return action::bind_kv_caches(temporal, depformer, temporal_positions, + depformer_positions); +} + using MoshiExecutor = sm; } // namespace emel::speech::generator::moshi::executor diff --git a/src/emel/speech/generator/moshi/executor/context.hpp b/src/emel/speech/generator/moshi/executor/context.hpp index 9d605650..3743d3a6 100644 --- a/src/emel/speech/generator/moshi/executor/context.hpp +++ b/src/emel/speech/generator/moshi/executor/context.hpp @@ -3,6 +3,7 @@ #include #include "emel/kernel/sm.hpp" +#include "emel/memory/streaming/sm.hpp" #include "emel/memory/view.hpp" #include "emel/model/data.hpp" #include "emel/model/moshi/detail.hpp" @@ -31,6 +32,8 @@ struct depformer_kv_binding { struct kv_bindings { temporal_kv_binding temporal = {}; depformer_kv_binding depformer = {}; + emel::memory::streaming::sm *temporal_positions = nullptr; + emel::memory::streaming::sm *depformer_positions = nullptr; }; struct runtime { @@ -59,12 +62,16 @@ struct context { : temporal_kv(kv_binding) {} explicit context(const kv_bindings &kv_binding_set) : temporal_kv(kv_binding_set.temporal), - depformer_kv(kv_binding_set.depformer) {} + depformer_kv(kv_binding_set.depformer), + temporal_positions(kv_binding_set.temporal_positions), + depformer_positions(kv_binding_set.depformer_positions) {} runtime session = {}; sampling_config sampling = {}; temporal_kv_binding temporal_kv = {}; depformer_kv_binding depformer_kv = {}; + emel::memory::streaming::sm *temporal_positions = nullptr; + emel::memory::streaming::sm *depformer_positions = nullptr; emel::kernel::sm kernel = {}; }; @@ -84,4 +91,17 @@ bind_kv_caches(const temporal_kv_binding &temporal, return kv_bindings{.temporal = temporal, .depformer = depformer}; } +inline kv_bindings +bind_kv_caches(const temporal_kv_binding &temporal, + const depformer_kv_binding &depformer, + emel::memory::streaming::sm &temporal_positions, + emel::memory::streaming::sm &depformer_positions) noexcept { + return kv_bindings{ + .temporal = temporal, + .depformer = depformer, + .temporal_positions = &temporal_positions, + .depformer_positions = &depformer_positions, + }; +} + } // namespace emel::speech::generator::moshi::executor::action diff --git a/src/emel/speech/generator/moshi/executor/detail.hpp b/src/emel/speech/generator/moshi/executor/detail.hpp index 69666455..128794fd 100644 --- a/src/emel/speech/generator/moshi/executor/detail.hpp +++ b/src/emel/speech/generator/moshi/executor/detail.hpp @@ -36,10 +36,8 @@ struct streaming_kv_view { std::span key_cache = {}; std::span value_cache = {}; std::span layer_cache_offsets = {}; - int32_t *offset = nullptr; int32_t layer_count = 0; int32_t position_capacity = 0; - int32_t block_tokens = 0; int32_t kv_dim = 0; }; @@ -280,28 +278,6 @@ inline bool tensor_shape(const tensor_record *tensor, const int64_t ne0, (tensor->n_dims == 1 || tensor->dims[1] == ne1); } -inline int32_t -current_logical_position(const emel::memory::view::snapshot &snapshot, - const int32_t sequence_id) noexcept { - const int32_t length = snapshot.sequence_length(sequence_id); - return length > 0 ? length - 1 : -1; -} - -inline int32_t physical_position(const emel::memory::view::snapshot &snapshot, - const int32_t sequence_id, - const int32_t logical_position) noexcept { - if (logical_position < 0 || snapshot.block_tokens <= 0) { - return -1; - } - const int32_t block_id = - snapshot.lookup_kv_block(sequence_id, logical_position); - if (block_id < 0) { - return -1; - } - return block_id * snapshot.block_tokens + - (logical_position % snapshot.block_tokens); -} - inline bool token_in_embedding_range(const int32_t token, const int32_t card) noexcept { return token >= k_token_zero && token <= card; diff --git a/src/emel/speech/generator/moshi/executor/events.hpp b/src/emel/speech/generator/moshi/executor/events.hpp index 0e2ae965..c70b3ccd 100644 --- a/src/emel/speech/generator/moshi/executor/events.hpp +++ b/src/emel/speech/generator/moshi/executor/events.hpp @@ -4,6 +4,7 @@ #include "emel/callback.hpp" #include "emel/error/error.hpp" +#include "emel/memory/streaming/events.hpp" #include "emel/model/data.hpp" #include "emel/speech/generator/moshi/events.hpp" #include "emel/speech/generator/moshi/executor/detail.hpp" @@ -48,6 +49,7 @@ struct step_ctx { bool embedding_row_ok = false; bool projection_view_bound = false; bool temporal_kv_bound = false; + bool temporal_position_accepted = false; bool temporal_layer_norm_rms_ok = false; bool temporal_layer_norm_ok = false; bool temporal_layer_projection_ok = false; @@ -68,6 +70,7 @@ struct step_ctx { bool text_logits_ok = false; bool text_sampling_ok = false; bool depformer_kv_bound = false; + bool depformer_position_accepted = false; bool depformer_input_ok = false; bool depformer_input_projection_bound = false; bool depformer_input_projection_ok = false; @@ -92,17 +95,17 @@ struct step_ctx { int32_t best_index = -1; int32_t input_audio_codebook_index = 0; int32_t temporal_layer_index = 0; - int32_t temporal_logical_position = -1; - int32_t temporal_physical_position = -1; + int32_t temporal_rope_position = -1; + int32_t temporal_position_error = 0; int32_t depformer_codebook_index = 0; int32_t depformer_weight_index = -1; int32_t depformer_layer_index = 0; - int32_t depformer_logical_position = -1; - int32_t depformer_physical_position = -1; - int32_t depformer_valid_positions = 0; + int32_t depformer_position_error = 0; float best_score = 0.0f; detail::temporal_kv_view temporal_kv = {}; detail::depformer_kv_view depformer_kv = {}; + emel::memory::streaming::advance_result temporal_position = {}; + emel::memory::streaming::advance_result depformer_position = {}; detail::tensor_view embedding_view = {}; detail::tensor_view projection_view = {}; alignas(64) std::array logits = {}; diff --git a/src/emel/speech/generator/moshi/executor/guards.hpp b/src/emel/speech/generator/moshi/executor/guards.hpp index 93794455..da0b4def 100644 --- a/src/emel/speech/generator/moshi/executor/guards.hpp +++ b/src/emel/speech/generator/moshi/executor/guards.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "emel/model/loader/errors.hpp" #include "emel/model/moshi/detail.hpp" #include "emel/speech/generator/moshi/executor/context.hpp" @@ -325,7 +327,8 @@ struct guard_temporal_kv_binding_present { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { (void)runtime_ev; - return ctx.temporal_kv.cache != nullptr && ctx.temporal_kv.bind != nullptr; + return ctx.temporal_kv.cache != nullptr && + ctx.temporal_kv.bind != nullptr && ctx.temporal_positions != nullptr; } }; @@ -343,7 +346,31 @@ struct guard_temporal_kv_bound { return runtime_ev.ctx.temporal_kv_bound && !view.key_cache.empty() && !view.value_cache.empty() && !view.layer_cache_offsets.empty() && view.layer_count > 0 && view.position_capacity > 0 && - view.block_tokens > 0 && view.kv_dim > 0; + view.kv_dim > 0; + } +}; + +struct guard_temporal_position_advance_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &result = runtime_ev.ctx.temporal_position; + const auto &window = result.window; + return runtime_ev.ctx.temporal_position_accepted && + runtime_ev.ctx.temporal_position_error == + static_cast( + emel::error::cast(emel::memory::streaming::error::none)) && + result.logical_position >= 0 && result.physical_position >= 0 && + result.physical_position < window.capacity && window.capacity > 0 && + window.logical_end == result.logical_position + 1 && + window.valid_positions > 0 && + window.valid_positions <= window.capacity; + } +}; + +struct guard_temporal_position_advance_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_position_advance_succeeded{}(runtime_ev, ctx); } }; @@ -447,19 +474,18 @@ struct guard_temporal_layer_rope_supported { const action::context &ctx) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t hidden_dim = ctx.session.hidden_dim; - const int32_t logical_position = detail::current_logical_position( - runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id); - const int32_t physical_position = detail::physical_position( - runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, - logical_position); + const auto &position = runtime_ev.ctx.temporal_position; const int32_t head_dim = lm.num_heads > 0 ? hidden_dim / lm.num_heads : 0; return runtime_ev.ctx.temporal_layer_projection_ok && hidden_dim > 0 && lm.num_heads > 0 && lm.max_period > 0 && hidden_dim % lm.num_heads == 0 && head_dim > 0 && (head_dim % 2) == 0 && static_cast(head_dim) <= detail::k_max_hidden_dim && - logical_position >= 0 && physical_position >= 0 && - physical_position < runtime_ev.ctx.temporal_kv.position_capacity; + position.logical_position >= 0 && + position.logical_position <= std::numeric_limits::max() && + position.physical_position >= 0 && + position.physical_position < + runtime_ev.ctx.temporal_kv.position_capacity; } }; @@ -494,13 +520,13 @@ struct guard_temporal_layer_cache_write_supported { view.kv_dim != hidden_dim || layer < 0 || layer >= view.layer_count || view.layer_cache_offsets.empty() || static_cast(layer) >= view.layer_cache_offsets.size() || - runtime_ev.ctx.temporal_physical_position < 0) { + runtime_ev.ctx.temporal_position.physical_position < 0) { return false; } const size_t layer_offset = view.layer_cache_offsets[static_cast(layer)]; const size_t physical_position = - static_cast(runtime_ev.ctx.temporal_physical_position); + static_cast(runtime_ev.ctx.temporal_position.physical_position); const size_t dim = static_cast(hidden_dim); const size_t begin = layer_offset + physical_position * dim; const size_t end = begin + dim; @@ -533,20 +559,22 @@ struct guard_temporal_layer_cache_write_failed { struct guard_temporal_layer_attention_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &snapshot = runtime_ev.request.memory_snapshot; const auto &view = runtime_ev.ctx.temporal_kv; + const auto &window = runtime_ev.ctx.temporal_position.window; const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t hidden_dim = ctx.session.hidden_dim; - const int32_t sequence_length = - snapshot.sequence_length(runtime_ev.request.sequence_id); const int32_t capacity = view.position_capacity; const int32_t head_dim = lm.num_heads > 0 ? hidden_dim / lm.num_heads : 0; const int32_t layer = runtime_ev.ctx.temporal_layer_index; if (!runtime_ev.ctx.temporal_layer_cache_write_ok || hidden_dim <= 0 || lm.num_heads <= 0 || hidden_dim % lm.num_heads != 0 || head_dim <= 0 || static_cast(head_dim) > detail::k_max_hidden_dim || - sequence_length <= 0 || capacity <= 0 || + window.valid_positions <= 0 || capacity <= 0 || static_cast(capacity) > detail::k_max_temporal_context || + window.capacity != capacity || window.valid_positions > capacity || + window.logical_begin < 0 || + window.logical_end - window.logical_begin != window.valid_positions || + window.physical_begin < 0 || window.physical_begin >= capacity || view.kv_dim != hidden_dim || layer < 0 || layer >= view.layer_count || view.layer_cache_offsets.empty() || static_cast(layer) >= view.layer_cache_offsets.size()) { @@ -555,22 +583,8 @@ struct guard_temporal_layer_attention_supported { const size_t layer_offset = view.layer_cache_offsets[static_cast(layer)]; const size_t dim = static_cast(hidden_dim); - const int32_t logical_begin = - sequence_length > capacity ? sequence_length - capacity : 0; - for (int32_t logical = logical_begin; logical < sequence_length; - ++logical) { - const int32_t physical = detail::physical_position( - snapshot, runtime_ev.request.sequence_id, logical); - if (physical < 0 || physical >= capacity) { - return false; - } - const size_t begin = layer_offset + static_cast(physical) * dim; - const size_t end = begin + dim; - if (end > view.key_cache.size() || end > view.value_cache.size()) { - return false; - } - } - return true; + const size_t end = layer_offset + static_cast(capacity) * dim; + return end <= view.key_cache.size() && end <= view.value_cache.size(); } }; @@ -1106,7 +1120,8 @@ struct guard_depformer_kv_binding_present { const action::context &ctx) const noexcept { (void)runtime_ev; return ctx.depformer_kv.cache != nullptr && - ctx.depformer_kv.bind != nullptr; + ctx.depformer_kv.bind != nullptr && + ctx.depformer_positions != nullptr; } }; @@ -1123,12 +1138,52 @@ struct guard_depformer_kv_bound { const auto &view = runtime_ev.ctx.depformer_kv; return runtime_ev.ctx.depformer_kv_bound && !view.key_cache.empty() && !view.value_cache.empty() && !view.layer_cache_offsets.empty() && - view.offset != nullptr && *view.offset >= 0 && view.layer_count > 0 && view.position_capacity > 0 && view.kv_dim > 0; } }; +struct guard_depformer_position_reset_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_position_accepted && + runtime_ev.ctx.depformer_position_error == + static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + } +}; + +struct guard_depformer_position_reset_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_position_reset_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_depformer_position_advance_succeeded { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + const auto &result = runtime_ev.ctx.depformer_position; + const auto &window = result.window; + return runtime_ev.ctx.depformer_position_accepted && + runtime_ev.ctx.depformer_position_error == + static_cast( + emel::error::cast(emel::memory::streaming::error::none)) && + result.logical_position >= 0 && result.physical_position >= 0 && + result.physical_position < window.capacity && window.capacity > 0 && + window.logical_end == result.logical_position + 1 && + window.valid_positions > 0 && + window.valid_positions <= window.capacity; + } +}; + +struct guard_depformer_position_advance_failed { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_position_advance_succeeded{}(runtime_ev, ctx); + } +}; + struct guard_depformer_kv_bind_failed { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { @@ -1413,15 +1468,16 @@ struct guard_depformer_layer_cache_write_supported { const auto &view = runtime_ev.ctx.depformer_kv; const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; - if (!runtime_ev.ctx.depformer_layer_projection_ok || - view.offset == nullptr || *view.offset < 0 || dep_dim <= 0 || + const int32_t physical = + runtime_ev.ctx.depformer_position.physical_position; + if (!runtime_ev.ctx.depformer_layer_projection_ok || dep_dim <= 0 || view.kv_dim != dep_dim || layer < 0 || layer >= view.layer_count || view.layer_cache_offsets.empty() || static_cast(layer) >= view.layer_cache_offsets.size() || - view.position_capacity <= 0) { + view.position_capacity <= 0 || physical < 0 || + physical >= view.position_capacity) { return false; } - const int32_t physical = *view.offset % view.position_capacity; const size_t layer_offset = view.layer_cache_offsets[static_cast(layer)]; const size_t begin = layer_offset + static_cast(physical) * @@ -1460,7 +1516,8 @@ struct guard_depformer_layer_attention_supported { const int32_t dep_dim = lm.depformer_dim; const int32_t head_dim = lm.depformer_num_heads > 0 ? dep_dim / lm.depformer_num_heads : 0; - const int32_t valid_positions = runtime_ev.ctx.depformer_valid_positions; + const auto &window = runtime_ev.ctx.depformer_position.window; + const int32_t valid_positions = window.valid_positions; const int32_t capacity = view.position_capacity; const int32_t layer = runtime_ev.ctx.depformer_layer_index; if (!runtime_ev.ctx.depformer_layer_cache_write_ok || dep_dim <= 0 || @@ -1469,8 +1526,12 @@ struct guard_depformer_layer_attention_supported { static_cast(head_dim) > detail::k_max_hidden_dim || valid_positions <= 0 || capacity <= 0 || static_cast(capacity) > detail::k_max_depformer_context || - valid_positions > capacity || view.kv_dim != dep_dim || layer < 0 || - layer >= view.layer_count || view.layer_cache_offsets.empty() || + valid_positions > capacity || window.capacity != capacity || + window.logical_begin < 0 || + window.logical_end - window.logical_begin != valid_positions || + window.physical_begin < 0 || window.physical_begin >= capacity || + view.kv_dim != dep_dim || layer < 0 || layer >= view.layer_count || + view.layer_cache_offsets.empty() || static_cast(layer) >= view.layer_cache_offsets.size()) { return false; } diff --git a/src/emel/speech/generator/moshi/executor/sm.hpp b/src/emel/speech/generator/moshi/executor/sm.hpp index 2bee5d2d..cee02fbb 100644 --- a/src/emel/speech/generator/moshi/executor/sm.hpp +++ b/src/emel/speech/generator/moshi/executor/sm.hpp @@ -42,6 +42,8 @@ struct state_input_audio_codebook_advance {}; struct state_input_embedding_result_decision {}; struct state_bind_temporal_kv {}; struct state_temporal_kv_result_decision {}; +struct state_temporal_position_result_decision {}; +struct state_temporal_position_valid_decision {}; struct state_temporal_layer_norm {}; struct state_temporal_layer_norm_rms_result_decision {}; struct state_temporal_layer_norm_scale {}; @@ -99,6 +101,9 @@ struct state_text_logits_sample_select {}; struct state_text_logits_result_decision {}; struct state_bind_depformer_kv {}; struct state_depformer_kv_result_decision {}; +struct state_depformer_position_reset_result_decision {}; +struct state_depformer_position_advance_result_decision {}; +struct state_depformer_weight_route_decision {}; struct state_depformer_weight_decision {}; struct state_depformer_input {}; struct state_depformer_input_projection_bind_result_decision {}; @@ -323,10 +328,24 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_temporal_kv_bind_failed{} ] / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state + , sml::state <= + sml::state + + sml::completion / action::effect_advance_temporal_position{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_temporal_position_advance_succeeded{} ] + , sml::state <= + sml::state + + sml::completion + [ guard::guard_temporal_position_advance_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= + sml::state + sml::completion [ guard::guard_temporal_layer_norm_supported{} ] / action::effect_run_temporal_layer_norm_rms{} - , sml::state <= sml::state + , sml::state <= + sml::state + sml::completion [ guard::guard_temporal_layer_norm_unsupported{} ] / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state @@ -612,17 +631,42 @@ struct model { / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_kv_bound{} ] - / action::effect_reset_depformer_kv_offset{} + / action::effect_reset_depformer_positions{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_kv_bind_failed{} ] / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state + , sml::state <= + sml::state + + sml::completion + , sml::state <= + sml::state + + sml::completion + [ guard::guard_depformer_position_reset_succeeded{} ] + / action::effect_advance_depformer_position{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_depformer_position_reset_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_depformer_position_advance_succeeded{} ] + , sml::state <= + sml::state + + sml::completion + [ guard::guard_depformer_position_advance_failed{} ] + / action::effect_mark_graph_execution_unsupported{} + , sml::state <= + sml::state + sml::completion [ guard::guard_depformer_scheduled_weight_present{} ] / action::effect_use_depformer_scheduled_weight{} - , sml::state <= sml::state + , sml::state <= + sml::state + sml::completion [ guard::guard_depformer_scheduled_weight_absent{} ] / action::effect_use_depformer_codebook_weight{} - , sml::state <= sml::state + , sml::state <= + sml::state + sml::completion [ guard::guard_depformer_scheduled_weight_invalid{} ] / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state @@ -913,15 +957,9 @@ struct model { / action::effect_advance_depformer_codebook{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_codebooks_complete{} ] - , sml::state <= sml::state - + sml::completion [ guard::guard_depformer_scheduled_weight_present{} ] - / action::effect_use_depformer_scheduled_weight{} - , sml::state <= sml::state - + sml::completion [ guard::guard_depformer_scheduled_weight_absent{} ] - / action::effect_use_depformer_codebook_weight{} - , sml::state <= sml::state - + sml::completion [ guard::guard_depformer_scheduled_weight_invalid{} ] - / action::effect_mark_graph_execution_unsupported{} + , sml::state <= + sml::state + + sml::completion / action::effect_advance_depformer_position{} , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] / action::effect_store_error_out{} diff --git a/src/emel/speech/generator/moshi/personaplex/session/actions.hpp b/src/emel/speech/generator/moshi/personaplex/session/actions.hpp index 306926be..8f9bd06b 100644 --- a/src/emel/speech/generator/moshi/personaplex/session/actions.hpp +++ b/src/emel/speech/generator/moshi/personaplex/session/actions.hpp @@ -22,6 +22,28 @@ void effect_store_error(const runtime_event_type &runtime_ev, } // namespace detail_ns +struct effect_initialize_temporal_positions { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + int32_t error_out = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.child_accepted = ctx.temporal_positions.process_event( + emel::memory::streaming::event::initialize{.error_out = error_out}); + runtime_ev.ctx.child_err = static_cast(error_out); + } +}; + +struct effect_initialize_depformer_positions { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + int32_t error_out = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.child_accepted = ctx.depformer_positions.process_event( + emel::memory::streaming::event::initialize{.error_out = error_out}); + runtime_ev.ctx.child_err = static_cast(error_out); + } +}; + struct effect_initialize_encoder { static void effect_capture_codec_initialize( event::initialize_ctx &runtime, diff --git a/src/emel/speech/generator/moshi/personaplex/session/context.hpp b/src/emel/speech/generator/moshi/personaplex/session/context.hpp index 7e14b196..56d34d51 100644 --- a/src/emel/speech/generator/moshi/personaplex/session/context.hpp +++ b/src/emel/speech/generator/moshi/personaplex/session/context.hpp @@ -1,6 +1,7 @@ #pragma once #include "emel/memory/hybrid/context.hpp" +#include "emel/memory/streaming/sm.hpp" #include "emel/speech/codec/mimi/any.hpp" #include "emel/speech/generator/moshi/any.hpp" #include "emel/speech/generator/moshi/executor/any.hpp" @@ -20,9 +21,14 @@ struct dependencies { struct context { explicit context(const dependencies &deps) : temporal_kv(deps.temporal_kv), depformer_kv(deps.depformer_kv), + temporal_positions(emel::memory::streaming::dependencies{ + .capacity = deps.temporal_kv.position_capacity}), + depformer_positions(emel::memory::streaming::dependencies{ + .capacity = deps.depformer_kv.position_capacity}), graph_executor(executor::bind_kv_caches( executor::bind_temporal_kv_cache(this, bind_temporal_cache), - executor::bind_depformer_kv_cache(this, bind_depformer_cache))), + executor::bind_depformer_kv_cache(this, bind_depformer_cache), + temporal_positions, depformer_positions)), generator(deps.generator_memory, moshi::action::bind_graph_executor( &graph_executor, executor::dispatch_graph_step)) {} @@ -45,6 +51,8 @@ struct context { executor::detail::temporal_kv_view temporal_kv = {}; executor::detail::depformer_kv_view depformer_kv = {}; + emel::memory::streaming::sm temporal_positions; + emel::memory::streaming::sm depformer_positions; int32_t frame_samples = 0; int32_t public_n_q = 0; mimi::sm encoder = {}; diff --git a/src/emel/speech/generator/moshi/personaplex/session/errors.hpp b/src/emel/speech/generator/moshi/personaplex/session/errors.hpp index e36ecdf1..7b17ff7f 100644 --- a/src/emel/speech/generator/moshi/personaplex/session/errors.hpp +++ b/src/emel/speech/generator/moshi/personaplex/session/errors.hpp @@ -7,6 +7,7 @@ namespace emel::speech::generator::moshi::personaplex::session::error { enum code : emel::error::type { none = 0, invalid_request, + memory_initialize_failed, codec_initialize_failed, executor_initialize_failed, generator_initialize_failed, diff --git a/src/emel/speech/generator/moshi/personaplex/session/guards.hpp b/src/emel/speech/generator/moshi/personaplex/session/guards.hpp index 694227c5..ec0ca5ea 100644 --- a/src/emel/speech/generator/moshi/personaplex/session/guards.hpp +++ b/src/emel/speech/generator/moshi/personaplex/session/guards.hpp @@ -50,25 +50,21 @@ struct guard_initialize_request_valid { lm.inference_dep_q == mimi.n_q && lm.card == mimi.card && ctx.temporal_kv.key_cache.data() != nullptr && ctx.temporal_kv.value_cache.data() != nullptr && - ctx.temporal_kv.offset != nullptr && ctx.temporal_kv.key_cache.size() >= temporal_elements && ctx.temporal_kv.value_cache.size() >= temporal_elements && ctx.temporal_kv.layer_cache_offsets.size() >= static_cast(lm.num_layers) && ctx.temporal_kv.layer_count == lm.num_layers && ctx.temporal_kv.position_capacity == lm.context && - ctx.temporal_kv.block_tokens > 0 && ctx.temporal_kv.kv_dim == lm.dim && ctx.depformer_kv.key_cache.data() != nullptr && ctx.depformer_kv.value_cache.data() != nullptr && - ctx.depformer_kv.offset != nullptr && ctx.depformer_kv.key_cache.size() >= depformer_elements && ctx.depformer_kv.value_cache.size() >= depformer_elements && ctx.depformer_kv.layer_cache_offsets.size() >= static_cast(lm.depformer_num_layers) && ctx.depformer_kv.layer_count == lm.depformer_num_layers && ctx.depformer_kv.position_capacity == lm.depformer_context && - ctx.depformer_kv.block_tokens > 0 && ctx.depformer_kv.kv_dim == lm.depformer_dim; } }; diff --git a/src/emel/speech/generator/moshi/personaplex/session/sm.hpp b/src/emel/speech/generator/moshi/personaplex/session/sm.hpp index ec270561..9bb66f38 100644 --- a/src/emel/speech/generator/moshi/personaplex/session/sm.hpp +++ b/src/emel/speech/generator/moshi/personaplex/session/sm.hpp @@ -12,6 +12,8 @@ namespace emel::speech::generator::moshi::personaplex::session { struct state_uninitialized {}; +struct state_initialize_temporal_positions_result {}; +struct state_initialize_depformer_positions_result {}; struct state_initialize_encoder_result {}; struct state_initialize_decoder_result {}; struct state_initialize_executor_result {}; @@ -48,9 +50,23 @@ struct model { return sml::make_transition_table( //------------------------------------------------------------------------------// // Initialize every child actor in deterministic RTC order. - sml::state <= *sml::state + sml::state <= *sml::state + sml::event [ guard::guard_initialize_request_valid{} ] + / action::effect_initialize_temporal_positions{} + , sml::state <= + sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_initialize_depformer_positions{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_initialize_child{} + , sml::state <= + sml::state + + sml::completion [ guard::guard_child_succeeded{} ] / action::effect_initialize_encoder{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_failed{} ] + / action::effect_fail_initialize_child{} , sml::state <= sml::state + sml::event [ guard::guard_initialize_request_invalid{} ] / action::effect_fail_initialize_invalid{} @@ -184,6 +200,10 @@ struct model { // Every external event outside its modeled phase is explicit. , sml::state <= sml::state + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_mark_unexpected{} , sml::state <= sml::state + sml::unexpected_event / action::effect_mark_unexpected{} , sml::state <= sml::state diff --git a/tests/speech/generator/moshi_executor_streaming_tests.cpp b/tests/speech/generator/moshi_executor_streaming_tests.cpp new file mode 100644 index 00000000..36953bc8 --- /dev/null +++ b/tests/speech/generator/moshi_executor_streaming_tests.cpp @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include + +#include + +#include "emel/error/error.hpp" +#include "emel/memory/streaming/sm.hpp" +#include "emel/speech/generator/moshi/any.hpp" +#include "emel/speech/generator/moshi/executor/any.hpp" +#include "moshi_fixture.hpp" + +namespace { + +namespace memory_streaming = emel::memory::streaming; +namespace moshi = emel::speech::generator::moshi; +namespace executor = emel::speech::generator::moshi::executor; +using emel::speech::generator::moshi::test::load_fixture_or_skip; + +struct cache_storage { + cache_storage(const int32_t layer_count, const int32_t capacity, + const int32_t dimension) + : key(static_cast(layer_count) * static_cast(capacity) * + static_cast(dimension)), + value(key.size()), offsets(static_cast(layer_count)) { + const size_t per_layer = + static_cast(capacity) * static_cast(dimension); + for (int32_t layer = 0; layer < layer_count; ++layer) { + offsets[static_cast(layer)] = + static_cast(layer) * per_layer; + } + } + + std::vector key; + std::vector value; + std::vector offsets; +}; + +bool bind_temporal_cache(void *storage_ptr, const emel::model::data &model, + const emel::memory::view::snapshot &, int32_t, + executor::detail::temporal_kv_view &view) noexcept { + auto &storage = *static_cast(storage_ptr); + view.key_cache = storage.key; + view.value_cache = storage.value; + view.layer_cache_offsets = storage.offsets; + view.layer_count = model.moshi_lm.num_layers; + view.position_capacity = model.moshi_lm.context; + view.kv_dim = model.moshi_lm.dim; + return true; +} + +bool bind_depformer_cache(void *storage_ptr, const emel::model::data &model, + const emel::memory::view::snapshot &, int32_t, + executor::detail::depformer_kv_view &view) noexcept { + auto &storage = *static_cast(storage_ptr); + view.key_cache = storage.key; + view.value_cache = storage.value; + view.layer_cache_offsets = storage.offsets; + view.layer_count = model.moshi_lm.depformer_num_layers; + view.position_capacity = model.moshi_lm.depformer_context; + view.kv_dim = model.moshi_lm.depformer_dim; + return true; +} + +memory_streaming::window_view capture(memory_streaming::sm &machine) { + memory_streaming::window_view view = {}; + int32_t err = + static_cast(emel::error::cast(memory_streaming::error::none)); + REQUIRE(machine.process_event(memory_streaming::event::capture_view{ + .view_out = view, .error_out = err})); + REQUIRE(err == static_cast( + emel::error::cast(memory_streaming::error::none))); + return view; +} + +} // namespace + +TEST_CASE( + "speech Moshi executor delegates ring positions to streaming actors") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + const auto &lm = fixture.model->moshi_lm; + + cache_storage temporal_cache{lm.num_layers, lm.context, lm.dim}; + cache_storage depformer_cache{lm.depformer_num_layers, lm.depformer_context, + lm.depformer_dim}; + memory_streaming::sm temporal_positions{ + memory_streaming::dependencies{.capacity = lm.context}}; + memory_streaming::sm depformer_positions{ + memory_streaming::dependencies{.capacity = lm.depformer_context}}; + int32_t memory_err = + static_cast(emel::error::cast(memory_streaming::error::none)); + REQUIRE(temporal_positions.process_event( + memory_streaming::event::initialize{.error_out = memory_err})); + REQUIRE(memory_err == static_cast( + emel::error::cast(memory_streaming::error::none))); + REQUIRE(depformer_positions.process_event( + memory_streaming::event::initialize{.error_out = memory_err})); + REQUIRE(memory_err == static_cast( + emel::error::cast(memory_streaming::error::none))); + + const auto temporal_binding = + executor::bind_temporal_kv_cache(&temporal_cache, bind_temporal_cache); + const auto depformer_binding = + executor::bind_depformer_kv_cache(&depformer_cache, bind_depformer_cache); + executor::sm machine{ + executor::bind_kv_caches(temporal_binding, depformer_binding, + temporal_positions, depformer_positions)}; + + emel::error::type err = emel::error::cast(executor::error::none); + executor::event::initialize initialize{*fixture.model}; + initialize.error_out = &err; + REQUIRE(machine.process_event(initialize)); + + std::array input = {}; + std::array output = {}; + input.fill(-1); + input[0] = lm.text_padding_id; + emel::memory::view::snapshot unused_snapshot = {}; + int32_t text_token = -1; + moshi::event::graph_step step{ + *fixture.model, unused_snapshot, + std::span{input.data(), static_cast(lm.n_q + 1)}, + std::span{output.data(), static_cast(lm.dep_q)}, + text_token}; + step.error_out = &err; + + REQUIRE(machine.process_event(step)); + CHECK(capture(temporal_positions).logical_end == 1); + CHECK(capture(depformer_positions).logical_end == lm.dep_q); + + REQUIRE(machine.process_event(step)); + CHECK(capture(temporal_positions).logical_end == 2); + CHECK(capture(depformer_positions).logical_end == lm.dep_q); +} diff --git a/tests/speech/generator/moshi_lifecycle_tests.cpp b/tests/speech/generator/moshi_lifecycle_tests.cpp index 9e98d242..d674bac5 100644 --- a/tests/speech/generator/moshi_lifecycle_tests.cpp +++ b/tests/speech/generator/moshi_lifecycle_tests.cpp @@ -11,6 +11,7 @@ #include #include "../../memory/recording_kv_actor.hpp" +#include "emel/memory/streaming/sm.hpp" #include "emel/model/moshi/detail.hpp" #include "emel/speech/codec/mimi/any.hpp" #include "emel/speech/generator/moshi/any.hpp" @@ -21,6 +22,7 @@ namespace { namespace moshi = emel::speech::generator::moshi; namespace moshi_executor = emel::speech::generator::moshi::executor; +namespace memory_streaming = emel::memory::streaming; namespace mimi = emel::speech::codec::mimi; namespace model_moshi = emel::model::moshi::detail; using emel::speech::generator::moshi::test::load_fixture_or_skip; @@ -75,7 +77,6 @@ struct depformer_kv_probe { int32_t call_count = 0; int32_t sequence_id = -1; int32_t sequence_length = -1; - int32_t offset = 0; std::vector key_cache = {}; std::vector value_cache = {}; std::vector layer_offsets = {}; @@ -261,7 +262,6 @@ bool temporal_kv_probe_bind(void *cache_ptr, const emel::model::data &model, view.layer_cache_offsets = probe.layer_offsets; view.layer_count = layer_count; view.position_capacity = position_capacity; - view.block_tokens = snapshot.block_tokens > 0 ? snapshot.block_tokens : 16; view.kv_dim = kv_dim; return true; } @@ -296,14 +296,21 @@ bool depformer_kv_probe_bind(void *cache_ptr, const emel::model::data &model, view.value_cache = std::span{probe.value_cache.data(), probe.value_cache.size()}; view.layer_cache_offsets = probe.layer_offsets; - view.offset = &probe.offset; view.layer_count = layer_count; view.position_capacity = position_capacity; - view.block_tokens = 1; view.kv_dim = kv_dim; return true; } +void initialize_streaming_position(memory_streaming::sm &position) { + int32_t err = + static_cast(emel::error::cast(memory_streaming::error::none)); + REQUIRE(position.process_event( + memory_streaming::event::initialize{.error_out = err})); + REQUIRE(err == static_cast( + emel::error::cast(memory_streaming::error::none))); +} + } // namespace TEST_CASE("speech_moshi_generator_rejects_step_before_initialize") { @@ -1476,7 +1483,6 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { step_ctx.temporal_kv.layer_cache_offsets = std::span{offsets}; step_ctx.temporal_kv.layer_count = 1; step_ctx.temporal_kv.position_capacity = 1; - step_ctx.temporal_kv.block_tokens = 1; step_ctx.temporal_kv.kv_dim = lm.dim; step_ctx.temporal_kv_bound = true; CHECK( @@ -1502,6 +1508,8 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { step_ctx.temporal_layer_projection_ok = true; CHECK(moshi_executor::guard::guard_temporal_layer_projection_succeeded{}( step_run, executor_ctx)); + step_ctx.temporal_position.logical_position = 0; + step_ctx.temporal_position.physical_position = 0; CHECK_FALSE(moshi_executor::guard::guard_temporal_layer_rope_unsupported{}( step_run, executor_ctx)); CHECK(moshi_executor::guard::guard_temporal_layer_rope_failed{}( @@ -1581,8 +1589,15 @@ TEST_CASE( } temporal_kv_probe probe{}; - moshi_executor::sm executor{ - moshi_executor::bind_temporal_kv_cache(&probe, temporal_kv_probe_bind)}; + memory_streaming::sm temporal_positions{memory_streaming::dependencies{ + .capacity = fixture.model->moshi_lm.context}}; + initialize_streaming_position(temporal_positions); + moshi_executor::action::kv_bindings bindings{ + .temporal = moshi_executor::bind_temporal_kv_cache( + &probe, temporal_kv_probe_bind), + .temporal_positions = &temporal_positions, + }; + moshi_executor::sm executor{bindings}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1617,9 +1632,7 @@ TEST_CASE( CHECK(probe.call_count == 1); CHECK(probe.sequence_id == 7); CHECK(probe.sequence_length == 3); - const size_t write_offset = - static_cast(snapshot.sequence_length_values[7] - 1) * - static_cast(fixture.model->moshi_lm.dim); + const size_t write_offset = 0; const size_t write_end = write_offset + static_cast(fixture.model->moshi_lm.dim); REQUIRE(write_end <= probe.key_cache.size()); @@ -1665,8 +1678,14 @@ TEST_CASE("speech_moshi_executor_accepts_personaplex_voice_embedding_step") { &temporal_probe, temporal_kv_probe_bind); const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( &depformer_probe, depformer_kv_probe_bind); - moshi_executor::sm executor{ - moshi_executor::bind_kv_caches(temporal_kv, depformer_kv)}; + memory_streaming::sm temporal_positions{memory_streaming::dependencies{ + .capacity = fixture.model->moshi_lm.context}}; + memory_streaming::sm depformer_positions{memory_streaming::dependencies{ + .capacity = fixture.model->moshi_lm.depformer_context}}; + initialize_streaming_position(temporal_positions); + initialize_streaming_position(depformer_positions); + moshi_executor::sm executor{moshi_executor::bind_kv_caches( + temporal_kv, depformer_kv, temporal_positions, depformer_positions)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1725,8 +1744,14 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { &temporal_probe, temporal_kv_probe_bind); const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( &depformer_probe, depformer_kv_probe_bind); - moshi_executor::sm executor{ - moshi_executor::bind_kv_caches(temporal_kv, depformer_kv)}; + memory_streaming::sm temporal_positions{memory_streaming::dependencies{ + .capacity = fixture.model->moshi_lm.context}}; + memory_streaming::sm depformer_positions{memory_streaming::dependencies{ + .capacity = fixture.model->moshi_lm.depformer_context}}; + initialize_streaming_position(temporal_positions); + initialize_streaming_position(depformer_positions); + moshi_executor::sm executor{moshi_executor::bind_kv_caches( + temporal_kv, depformer_kv, temporal_positions, depformer_positions)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1744,7 +1769,6 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { snapshot.sequence_kv_block_count[7] = 1; snapshot.sequence_kv_blocks[7][0] = 0; err = emel::error::cast(moshi_executor::error::none); - depformer_probe.offset = 37; moshi::event::graph_step step{ *fixture.model, snapshot, @@ -1760,7 +1784,13 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { CHECK(err == emel::error::cast(moshi_executor::error::none)); CHECK(temporal_probe.call_count == 1); CHECK(depformer_probe.call_count == 1); - CHECK(depformer_probe.offset == fixture.model->moshi_lm.dep_q); + memory_streaming::window_view depformer_window = {}; + int32_t memory_err = + static_cast(emel::error::cast(memory_streaming::error::none)); + REQUIRE( + depformer_positions.process_event(memory_streaming::event::capture_view{ + .view_out = depformer_window, .error_out = memory_err})); + CHECK(depformer_window.logical_end == fixture.model->moshi_lm.dep_q); CHECK(text_token >= 0); CHECK(text_token < fixture.model->moshi_lm.text_card); for (int32_t index = 0; index < fixture.model->moshi_lm.dep_q; ++index) { @@ -1799,16 +1829,31 @@ TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { temporal_kv_probe second_temporal{}; depformer_kv_probe first_depformer{}; depformer_kv_probe second_depformer{}; + memory_streaming::sm first_temporal_positions{memory_streaming::dependencies{ + .capacity = first_fixture.model->moshi_lm.context}}; + memory_streaming::sm first_depformer_positions{memory_streaming::dependencies{ + .capacity = first_fixture.model->moshi_lm.depformer_context}}; + memory_streaming::sm second_temporal_positions{memory_streaming::dependencies{ + .capacity = second_fixture.model->moshi_lm.context}}; + memory_streaming::sm second_depformer_positions{ + memory_streaming::dependencies{ + .capacity = second_fixture.model->moshi_lm.depformer_context}}; + initialize_streaming_position(first_temporal_positions); + initialize_streaming_position(first_depformer_positions); + initialize_streaming_position(second_temporal_positions); + initialize_streaming_position(second_depformer_positions); moshi_executor::sm first{moshi_executor::bind_kv_caches( moshi_executor::bind_temporal_kv_cache(&first_temporal, temporal_kv_probe_bind), moshi_executor::bind_depformer_kv_cache(&first_depformer, - depformer_kv_probe_bind))}; + depformer_kv_probe_bind), + first_temporal_positions, first_depformer_positions)}; moshi_executor::sm second{moshi_executor::bind_kv_caches( moshi_executor::bind_temporal_kv_cache(&second_temporal, temporal_kv_probe_bind), moshi_executor::bind_depformer_kv_cache(&second_depformer, - depformer_kv_probe_bind))}; + depformer_kv_probe_bind), + second_temporal_positions, second_depformer_positions)}; emel::error::type first_err = emel::error::cast(moshi_executor::error::none); emel::error::type second_err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize first_init{*first_fixture.model}; @@ -1917,8 +1962,14 @@ TEST_CASE("speech_moshi_e2e_encodes_audio_generates_tokens_and_decodes_audio") { &temporal_probe, temporal_kv_probe_bind); const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( &depformer_probe, depformer_kv_probe_bind); - moshi_executor::sm executor{ - moshi_executor::bind_kv_caches(temporal_kv, depformer_kv)}; + memory_streaming::sm temporal_positions{memory_streaming::dependencies{ + .capacity = lm_fixture.model->moshi_lm.context}}; + memory_streaming::sm depformer_positions{memory_streaming::dependencies{ + .capacity = lm_fixture.model->moshi_lm.depformer_context}}; + initialize_streaming_position(temporal_positions); + initialize_streaming_position(depformer_positions); + moshi_executor::sm executor{moshi_executor::bind_kv_caches( + temporal_kv, depformer_kv, temporal_positions, depformer_positions)}; emel::error::type executor_err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize executor_init{*lm_fixture.model}; diff --git a/tests/speech/generator/moshi_personaplex_session_tests.cpp b/tests/speech/generator/moshi_personaplex_session_tests.cpp index dc2003c5..813d2438 100644 --- a/tests/speech/generator/moshi_personaplex_session_tests.cpp +++ b/tests/speech/generator/moshi_personaplex_session_tests.cpp @@ -50,8 +50,6 @@ TEST_CASE("PersonaPlex session runs its injected actors end to end") { temporal_offsets[static_cast(layer)] = static_cast(layer) * temporal_per_layer; } - int32_t temporal_offset = 0; - const size_t depformer_per_layer = static_cast(lm_config.depformer_context) * static_cast(lm_config.depformer_dim); @@ -65,18 +63,14 @@ TEST_CASE("PersonaPlex session runs its injected actors end to end") { depformer_offsets[static_cast(layer)] = static_cast(layer) * depformer_per_layer; } - int32_t depformer_offset = 0; - personaplex::dependencies dependencies{ .temporal_kv = { .key_cache = std::span{temporal_keys}, .value_cache = std::span{temporal_values}, .layer_cache_offsets = std::span{temporal_offsets}, - .offset = &temporal_offset, .layer_count = lm_config.num_layers, .position_capacity = lm_config.context, - .block_tokens = 1, .kv_dim = lm_config.dim, }, .depformer_kv = @@ -84,10 +78,8 @@ TEST_CASE("PersonaPlex session runs its injected actors end to end") { .key_cache = std::span{depformer_keys}, .value_cache = std::span{depformer_values}, .layer_cache_offsets = std::span{depformer_offsets}, - .offset = &depformer_offset, .layer_count = lm_config.depformer_num_layers, .position_capacity = lm_config.depformer_context, - .block_tokens = 1, .kv_dim = lm_config.depformer_dim, }, }; @@ -220,10 +212,6 @@ TEST_CASE("PersonaPlex session runs its injected actors end to end") { guard_context->temporal_kv.value_cache = {}; CHECK_FALSE(request_is_valid()); guard_context->temporal_kv.value_cache = temporal_value_view; - int32_t *const temporal_offset_ptr = guard_context->temporal_kv.offset; - guard_context->temporal_kv.offset = nullptr; - CHECK_FALSE(request_is_valid()); - guard_context->temporal_kv.offset = temporal_offset_ptr; const auto temporal_layer_views = guard_context->temporal_kv.layer_cache_offsets; guard_context->temporal_kv.layer_cache_offsets = {}; @@ -235,9 +223,6 @@ TEST_CASE("PersonaPlex session runs its injected actors end to end") { --guard_context->temporal_kv.position_capacity; CHECK_FALSE(request_is_valid()); ++guard_context->temporal_kv.position_capacity; - guard_context->temporal_kv.block_tokens = 0; - CHECK_FALSE(request_is_valid()); - guard_context->temporal_kv.block_tokens = 1; --guard_context->temporal_kv.kv_dim; CHECK_FALSE(request_is_valid()); ++guard_context->temporal_kv.kv_dim; @@ -250,10 +235,6 @@ TEST_CASE("PersonaPlex session runs its injected actors end to end") { guard_context->depformer_kv.value_cache = {}; CHECK_FALSE(request_is_valid()); guard_context->depformer_kv.value_cache = depformer_value_view; - int32_t *const depformer_offset_ptr = guard_context->depformer_kv.offset; - guard_context->depformer_kv.offset = nullptr; - CHECK_FALSE(request_is_valid()); - guard_context->depformer_kv.offset = depformer_offset_ptr; const auto depformer_layer_views = guard_context->depformer_kv.layer_cache_offsets; guard_context->depformer_kv.layer_cache_offsets = {}; @@ -265,9 +246,6 @@ TEST_CASE("PersonaPlex session runs its injected actors end to end") { --guard_context->depformer_kv.position_capacity; CHECK_FALSE(request_is_valid()); ++guard_context->depformer_kv.position_capacity; - guard_context->depformer_kv.block_tokens = 0; - CHECK_FALSE(request_is_valid()); - guard_context->depformer_kv.block_tokens = 1; --guard_context->depformer_kv.kv_dim; CHECK_FALSE(request_is_valid()); ++guard_context->depformer_kv.kv_dim; diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index d717fce1..026d41a0 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -63,7 +63,6 @@ struct streaming_cache { std::vector key_cache = {}; std::vector value_cache = {}; std::vector layer_offsets = {}; - int32_t offset = 0; }; bool read_binary_file(const std::filesystem::path &path, @@ -276,7 +275,6 @@ bool prepare_streaming_cache(streaming_cache &cache, const int32_t layer_count, } cache.key_cache.assign(static_cast(layer_count) * per_layer, 0u); cache.value_cache.assign(cache.key_cache.size(), 0u); - cache.offset = 0; return true; } @@ -433,10 +431,8 @@ int main(int argc, char **argv) { .value_cache = std::span{temporal_cache.value_cache}, .layer_cache_offsets = std::span{temporal_cache.layer_offsets}, - .offset = &temporal_cache.offset, .layer_count = lm_model.model->moshi_lm.num_layers, .position_capacity = lm_model.model->moshi_lm.context, - .block_tokens = 1, .kv_dim = lm_model.model->moshi_lm.dim, }, .depformer_kv = @@ -445,10 +441,8 @@ int main(int argc, char **argv) { .value_cache = std::span{depformer_cache.value_cache}, .layer_cache_offsets = std::span{depformer_cache.layer_offsets}, - .offset = &depformer_cache.offset, .layer_count = lm_model.model->moshi_lm.depformer_num_layers, .position_capacity = lm_model.model->moshi_lm.depformer_context, - .block_tokens = 1, .kv_dim = lm_model.model->moshi_lm.depformer_dim, }, .generator_memory = emel::memory::hybrid::kv_binding{}, From 8cf0988476c0e90c44d4a7eaa2c58eee42a9b97e Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 08:18:31 -0500 Subject: [PATCH 09/61] feat: add Moshi speech tokenizer actor --- .../mermaid/speech_tokenizer_moshi.mmd | 60 +++ .../architecture/speech_tokenizer_moshi.md | 130 +++++++ CMakeLists.txt | 1 + README.md | 1 + src/emel/speech/tokenizer/moshi/actions.hpp | 210 +++++++++++ src/emel/speech/tokenizer/moshi/any.hpp | 9 + src/emel/speech/tokenizer/moshi/context.hpp | 34 ++ src/emel/speech/tokenizer/moshi/detail.hpp | 51 +++ src/emel/speech/tokenizer/moshi/errors.hpp | 18 + src/emel/speech/tokenizer/moshi/events.hpp | 50 +++ src/emel/speech/tokenizer/moshi/guards.hpp | 283 ++++++++++++++ src/emel/speech/tokenizer/moshi/sm.hpp | 275 ++++++++++++++ .../tokenizer/moshi/lifecycle_tests.cpp | 352 ++++++++++++++++++ 13 files changed, 1474 insertions(+) create mode 100644 .planning/architecture/mermaid/speech_tokenizer_moshi.mmd create mode 100644 .planning/architecture/speech_tokenizer_moshi.md create mode 100644 src/emel/speech/tokenizer/moshi/actions.hpp create mode 100644 src/emel/speech/tokenizer/moshi/any.hpp create mode 100644 src/emel/speech/tokenizer/moshi/context.hpp create mode 100644 src/emel/speech/tokenizer/moshi/detail.hpp create mode 100644 src/emel/speech/tokenizer/moshi/errors.hpp create mode 100644 src/emel/speech/tokenizer/moshi/events.hpp create mode 100644 src/emel/speech/tokenizer/moshi/guards.hpp create mode 100644 src/emel/speech/tokenizer/moshi/sm.hpp create mode 100644 tests/speech/tokenizer/moshi/lifecycle_tests.cpp diff --git a/.planning/architecture/mermaid/speech_tokenizer_moshi.mmd b/.planning/architecture/mermaid/speech_tokenizer_moshi.mmd new file mode 100644 index 00000000..b74fc882 --- /dev/null +++ b/.planning/architecture/mermaid/speech_tokenizer_moshi.mmd @@ -0,0 +1,60 @@ +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_ready : initialize [guard_configuration_valid_] / effect_initialize_ + state_uninitialized --> state_uninitialized : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_ready --> state_ready : initialize [always] / already_initialized__ + state_prepared_full --> state_prepared_full : initialize [always] / already_initialized__ + state_prepared_generated --> state_prepared_generated : initialize [always] / already_initialized__ + state_errored --> state_ready : initialize [guard_configuration_valid_] / effect_initialize_ + state_errored --> state_errored : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_ready --> state_prepared_full : tokenize [guard_tokenize_full_] / effect_tokenize_full_ + state_ready --> state_prepared_generated : tokenize [guard_tokenize_tail_] / effect_tokenize_tail_ + state_ready --> state_prepared_generated : tokenize [guard_tokenize_empty_] / effect_tokenize_empty_ + state_ready --> state_ready : tokenize [guard_tokenize_invalid_] / request_shape__ + state_ready --> state_ready : tokenize [guard_tokenize_position_overflow_] / position_overflow__ + state_prepared_full --> state_prepared_full : tokenize [always] / phase_order__ + state_prepared_generated --> state_prepared_generated : tokenize [always] / phase_order__ + state_prepared_full --> state_commit_full_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ + state_prepared_full --> state_commit_full_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ + state_prepared_generated --> state_commit_generated_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ + state_prepared_generated --> state_commit_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ + state_prepared_full --> state_prepared_full : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ + state_prepared_generated --> state_prepared_generated : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ + state_prepared_full --> state_prepared_full : detokenize_run [guard_position_overflow_] / position_overflow__ + state_prepared_generated --> state_prepared_generated : detokenize_run [guard_position_overflow_] / position_overflow__ + state_commit_full_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ + state_commit_full_generated --> state_output_decision : completion_detokenize_run_ [always] / generated__ + state_commit_generated_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ + state_commit_generated --> state_output_decision : completion_detokenize_run_ [always] / generated__ + state_output_decision --> state_ready : completion_detokenize_run_ [guard_before_output_delay_] / effect_publish_no_output_ + state_output_decision --> state_output_validation : completion_detokenize_run_ [guard_past_output_delay_] / effect_collect_output_ + state_output_validation --> state_ready : completion_detokenize_run_ [guard_output_complete_] / effect_publish_output_ + state_output_validation --> state_ready : completion_detokenize_run_ [guard_output_incomplete_] / effect_publish_no_output_ + state_ready --> state_ready : restore_cache [guard_restore_valid_] / effect_restore_column_major_cache_ + state_ready --> state_ready : restore_cache [guard_restore_invalid_] / request_shape__ + state_prepared_full --> state_prepared_full : restore_cache [always] / phase_order__ + state_prepared_generated --> state_prepared_generated : restore_cache [always] / phase_order__ + state_prepared_full --> state_ready : advance [guard_advance_position_available_] / effect_advance_ + state_prepared_full --> state_prepared_full : advance [guard_advance_position_overflow_] / position_overflow__ + state_prepared_generated --> state_prepared_generated : advance [always] / phase_order__ + state_ready --> state_ready : advance [always] / phase_order__ + state_ready --> state_ready : reset [always] / effect_reset_ + state_prepared_full --> state_ready : reset [always] / effect_reset_ + state_prepared_generated --> state_ready : reset [always] / effect_reset_ + state_errored --> state_ready : reset [always] / effect_reset_ + state_uninitialized --> state_uninitialized : tokenize [always] / uninitialized__ + state_uninitialized --> state_uninitialized : detokenize_run [always] / uninitialized__ + state_uninitialized --> state_uninitialized : restore_cache [always] / uninitialized__ + state_uninitialized --> state_uninitialized : advance [always] / uninitialized__ + state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ + state_ready --> state_ready : detokenize_run [always] / phase_order__ + state_errored --> state_errored : tokenize [always] / internal_error__ + state_errored --> state_errored : detokenize_run [always] / internal_error__ + state_errored --> state_errored : restore_cache [always] / internal_error__ + state_errored --> state_errored : advance [always] / internal_error__ + state_uninitialized --> state_errored : _ [always] / effect_unexpected_ + state_ready --> state_errored : _ [always] / effect_unexpected_ + state_prepared_full --> state_errored : _ [always] / effect_unexpected_ + state_prepared_generated --> state_errored : _ [always] / effect_unexpected_ + state_errored --> state_errored : _ [always] / effect_unexpected_ diff --git a/.planning/architecture/speech_tokenizer_moshi.md b/.planning/architecture/speech_tokenizer_moshi.md new file mode 100644 index 00000000..053d33ab --- /dev/null +++ b/.planning/architecture/speech_tokenizer_moshi.md @@ -0,0 +1,130 @@ +# speech_tokenizer_moshi + +Source: [`emel/speech/tokenizer/moshi/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) + +## Mermaid + +```mermaid +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_ready : initialize [guard_configuration_valid_] / effect_initialize_ + state_uninitialized --> state_uninitialized : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_ready --> state_ready : initialize [always] / already_initialized__ + state_prepared_full --> state_prepared_full : initialize [always] / already_initialized__ + state_prepared_generated --> state_prepared_generated : initialize [always] / already_initialized__ + state_errored --> state_ready : initialize [guard_configuration_valid_] / effect_initialize_ + state_errored --> state_errored : initialize [guard_configuration_invalid_] / invalid_configuration__ + state_ready --> state_prepared_full : tokenize [guard_tokenize_full_] / effect_tokenize_full_ + state_ready --> state_prepared_generated : tokenize [guard_tokenize_tail_] / effect_tokenize_tail_ + state_ready --> state_prepared_generated : tokenize [guard_tokenize_empty_] / effect_tokenize_empty_ + state_ready --> state_ready : tokenize [guard_tokenize_invalid_] / request_shape__ + state_ready --> state_ready : tokenize [guard_tokenize_position_overflow_] / position_overflow__ + state_prepared_full --> state_prepared_full : tokenize [always] / phase_order__ + state_prepared_generated --> state_prepared_generated : tokenize [always] / phase_order__ + state_prepared_full --> state_commit_full_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ + state_prepared_full --> state_commit_full_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ + state_prepared_generated --> state_commit_generated_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ + state_prepared_generated --> state_commit_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ + state_prepared_full --> state_prepared_full : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ + state_prepared_generated --> state_prepared_generated : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ + state_prepared_full --> state_prepared_full : detokenize_run [guard_position_overflow_] / position_overflow__ + state_prepared_generated --> state_prepared_generated : detokenize_run [guard_position_overflow_] / position_overflow__ + state_commit_full_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ + state_commit_full_generated --> state_output_decision : completion_detokenize_run_ [always] / generated__ + state_commit_generated_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ + state_commit_generated --> state_output_decision : completion_detokenize_run_ [always] / generated__ + state_output_decision --> state_ready : completion_detokenize_run_ [guard_before_output_delay_] / effect_publish_no_output_ + state_output_decision --> state_output_validation : completion_detokenize_run_ [guard_past_output_delay_] / effect_collect_output_ + state_output_validation --> state_ready : completion_detokenize_run_ [guard_output_complete_] / effect_publish_output_ + state_output_validation --> state_ready : completion_detokenize_run_ [guard_output_incomplete_] / effect_publish_no_output_ + state_ready --> state_ready : restore_cache [guard_restore_valid_] / effect_restore_column_major_cache_ + state_ready --> state_ready : restore_cache [guard_restore_invalid_] / request_shape__ + state_prepared_full --> state_prepared_full : restore_cache [always] / phase_order__ + state_prepared_generated --> state_prepared_generated : restore_cache [always] / phase_order__ + state_prepared_full --> state_ready : advance [guard_advance_position_available_] / effect_advance_ + state_prepared_full --> state_prepared_full : advance [guard_advance_position_overflow_] / position_overflow__ + state_prepared_generated --> state_prepared_generated : advance [always] / phase_order__ + state_ready --> state_ready : advance [always] / phase_order__ + state_ready --> state_ready : reset [always] / effect_reset_ + state_prepared_full --> state_ready : reset [always] / effect_reset_ + state_prepared_generated --> state_ready : reset [always] / effect_reset_ + state_errored --> state_ready : reset [always] / effect_reset_ + state_uninitialized --> state_uninitialized : tokenize [always] / uninitialized__ + state_uninitialized --> state_uninitialized : detokenize_run [always] / uninitialized__ + state_uninitialized --> state_uninitialized : restore_cache [always] / uninitialized__ + state_uninitialized --> state_uninitialized : advance [always] / uninitialized__ + state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ + state_ready --> state_ready : detokenize_run [always] / phase_order__ + state_errored --> state_errored : tokenize [always] / internal_error__ + state_errored --> state_errored : detokenize_run [always] / internal_error__ + state_errored --> state_errored : restore_cache [always] / internal_error__ + state_errored --> state_errored : advance [always] / internal_error__ + state_uninitialized --> state_errored : _ [always] / effect_unexpected_ + state_ready --> state_errored : _ [always] / effect_unexpected_ + state_prepared_full --> state_errored : _ [always] / effect_unexpected_ + state_prepared_generated --> state_errored : _ [always] / effect_unexpected_ + state_errored --> state_errored : _ [always] / effect_unexpected_ +``` + +## Transitions + +| Source | Event | Guard | Action | Target | +| --- | --- | --- | --- | --- | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_configuration_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_configuration_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`invalid_configuration>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_configuration_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_configuration_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`invalid_configuration>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_full>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_tokenize_full>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_tail>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_tokenize_tail>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_empty>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_tokenize_empty>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_replace>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_full_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_full_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_replace>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_generated_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_commit_full_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`zero>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_commit_full_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`generated>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_commit_generated_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`zero>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_commit_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`generated>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_before_output_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_past_output_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_collect_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_validation`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_output_validation`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_output_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_publish_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_output_validation`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_output_incomplete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_restore_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_restore_column_major_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_restore_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_advance_position_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_advance>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_advance_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | diff --git a/CMakeLists.txt b/CMakeLists.txt index 801fe4cb..6f47cad3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,6 +196,7 @@ if(EMEL_ENABLE_TESTS) tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp tests/speech/recognizer/lifecycle_tests.cpp + tests/speech/tokenizer/moshi/lifecycle_tests.cpp tests/speech/tokenizer/whisper_tests.cpp tests/embeddings/text_embedding_lane_tests.cpp tests/embeddings/vision_embedding_lane_tests.cpp diff --git a/README.md b/README.md index d0bf85e2..e89714e5 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/speech_generator_moshi_executor.md`](.planning/architecture/speech_generator_moshi_executor.md) - [`.planning/architecture/speech_generator_moshi_personaplex_session.md`](.planning/architecture/speech_generator_moshi_personaplex_session.md) - [`.planning/architecture/speech_generator_moshi.md`](.planning/architecture/speech_generator_moshi.md) +- [`.planning/architecture/speech_tokenizer_moshi.md`](.planning/architecture/speech_tokenizer_moshi.md) - [`.planning/architecture/tensor_view.md`](.planning/architecture/tensor_view.md) - [`.planning/architecture/text_conditioner.md`](.planning/architecture/text_conditioner.md) - [`.planning/architecture/text_detokenizer.md`](.planning/architecture/text_detokenizer.md) diff --git a/src/emel/speech/tokenizer/moshi/actions.hpp b/src/emel/speech/tokenizer/moshi/actions.hpp new file mode 100644 index 00000000..55c48d4c --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/actions.hpp @@ -0,0 +1,210 @@ +#pragma once + +#include +#include +#include + +#include "emel/error/error.hpp" +#include "emel/speech/tokenizer/moshi/context.hpp" +#include "emel/speech/tokenizer/moshi/detail.hpp" +#include "emel/speech/tokenizer/moshi/errors.hpp" +#include "emel/speech/tokenizer/moshi/events.hpp" + +namespace emel::speech::tokenizer::moshi::action { + +inline int32_t error_code(const error value) noexcept { + return static_cast(emel::error::cast(value)); +} + +struct effect_initialize { + void operator()(const event::initialize &ev, context &ctx) const noexcept { + std::fill(ctx.config.cache.begin(), ctx.config.cache.end(), + ctx.config.token_ungenerated); + ctx.offset = 0; + ev.error_out = error_code(error::none); + } +}; + +struct effect_reset { + void operator()(const event::reset &ev, context &ctx) const noexcept { + std::fill(ctx.config.cache.begin(), ctx.config.cache.end(), + ctx.config.token_ungenerated); + ctx.offset = 0; + ev.error_out = error_code(error::none); + } +}; + +struct effect_restore_column_major_cache { + void operator()(const event::restore_cache &ev, context &ctx) const noexcept { + for (int32_t row = 0; row < ctx.config.cache_rows; ++row) { + for (int32_t codebook = 0; codebook < ctx.config.codebooks; ++codebook) { + const size_t source = static_cast(row) + + static_cast(codebook) * + static_cast(ctx.config.cache_rows); + detail::cache_at(ctx, row, codebook) = ev.column_major_cache[source]; + } + } + ctx.offset = ev.offset; + ev.error_out = error_code(error::none); + } +}; + +struct effect_advance { + void operator()(const event::advance &ev, context &ctx) const noexcept { + ++ctx.offset; + ev.error_out = error_code(error::none); + } +}; + +struct effect_tokenize_full { + void operator()(const event::tokenize &ev, context &ctx) const noexcept { + for (int32_t codebook = 0; codebook < ctx.config.codebooks; ++codebook) { + const int32_t row = detail::compute_cache_row( + ctx, ctx.offset + ctx.config.delays[static_cast(codebook)]); + detail::cache_at(ctx, row, codebook) = + ev.audio_tokens[static_cast(codebook)]; + } + detail::compute_model_tokens(ev, ctx); + ev.error_out = error_code(error::none); + } +}; + +struct effect_tokenize_tail { + void operator()(const event::tokenize &ev, context &ctx) const noexcept { + const int32_t first_codebook = ctx.config.delayed_audio_codebooks + 1; + const int32_t needed = ctx.config.codebooks - first_codebook; + for (int32_t tail = 0; tail < needed; ++tail) { + const int32_t codebook = first_codebook + tail; + const int32_t row = detail::compute_cache_row( + ctx, ctx.offset + ctx.config.delays[static_cast(codebook)]); + detail::cache_at(ctx, row, codebook) = + ev.audio_tokens[static_cast(tail)]; + } + detail::compute_model_tokens(ev, ctx); + ev.error_out = error_code(error::none); + } +}; + +struct effect_tokenize_empty { + void operator()(const event::tokenize &ev, + const context &ctx) const noexcept { + detail::compute_model_tokens(ev, ctx); + ev.error_out = error_code(error::none); + } +}; + +struct effect_begin_detokenize { + void operator()(const event::detokenize_run &runtime_ev, + const context &ctx) const noexcept { + runtime_ev.ctx.source_offset = ctx.offset; + runtime_ev.request.text_token_out = ctx.config.token_zero; + std::fill(runtime_ev.request.audio_tokens_out.begin(), + runtime_ev.request.audio_tokens_out.end(), ctx.config.token_zero); + runtime_ev.request.produced_out = false; + runtime_ev.request.error_out = error_code(error::none); + } +}; + +enum class cache_write_mode : uint8_t { + replace, + preserve_provided, +}; + +enum class audio_write_mode : uint8_t { + zero, + generated, +}; + +template +struct effect_commit_generated { + void operator()(const event::detokenize_run &runtime_ev, + context &ctx) const noexcept { + ctx.offset = runtime_ev.ctx.source_offset + 1; + const int32_t row = detail::compute_cache_row(ctx, ctx.offset); + detail::cache_at(ctx, row, 0) = runtime_ev.request.text_token; + + for (int32_t audio_codebook = 0; + audio_codebook < ctx.config.generated_audio_codebooks; + ++audio_codebook) { + const int32_t codebook = audio_codebook + 1; + int32_t token = ctx.config.token_zero; + if constexpr (audio_mode == audio_write_mode::generated) { + const int32_t masked = static_cast( + ctx.config.initial_delay_frames > 0 && + runtime_ev.ctx.source_offset < + static_cast( + ctx.config.delays[static_cast(codebook)]) + + static_cast(ctx.config.initial_delay_frames)); + token = masked * ctx.config.token_zero + + (1 - masked) * + runtime_ev.request + .audio_tokens[static_cast(audio_codebook)]; + } + + if constexpr (cache_mode == cache_write_mode::preserve_provided) { + const int32_t current = detail::cache_at(ctx, row, codebook); + const int32_t missing = + static_cast(current == ctx.config.token_ungenerated); + token = missing * token + (1 - missing) * current; + } + detail::cache_at(ctx, row, codebook) = token; + } + runtime_ev.request.error_out = error_code(error::none); + } +}; + +struct effect_collect_output { + void operator()(const event::detokenize_run &runtime_ev, + const context &ctx) const noexcept { + int32_t row = detail::compute_cache_row( + ctx, ctx.offset - ctx.config.maximum_delay + ctx.config.delays[0]); + runtime_ev.request.text_token_out = detail::cache_at(ctx, row, 0); + for (int32_t audio_codebook = 0; + audio_codebook < ctx.config.delayed_audio_codebooks; + ++audio_codebook) { + const int32_t codebook = audio_codebook + 1; + row = detail::compute_cache_row( + ctx, ctx.offset - ctx.config.maximum_delay + + ctx.config.delays[static_cast(codebook)]); + runtime_ev.request.audio_tokens_out[static_cast(audio_codebook)] = + detail::cache_at(ctx, row, codebook); + } + } +}; + +struct effect_publish_output { + void operator()(const event::detokenize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.produced_out = true; + runtime_ev.request.error_out = error_code(error::none); + } +}; + +struct effect_publish_no_output { + void operator()(const event::detokenize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.produced_out = false; + runtime_ev.request.error_out = error_code(error::none); + } +}; + +template struct effect_reject { + template + void operator()(const event_type &ev, const context &) const noexcept { + ev.error_out = error_code(error_value); + } +}; + +template struct effect_reject_detokenize { + void operator()(const event::detokenize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.error_out = error_code(error_value); + } +}; + +struct effect_unexpected { + template + void operator()(const event_type &, const context &) const noexcept {} +}; + +} // namespace emel::speech::tokenizer::moshi::action diff --git a/src/emel/speech/tokenizer/moshi/any.hpp b/src/emel/speech/tokenizer/moshi/any.hpp new file mode 100644 index 00000000..bcb4c219 --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/any.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "emel/speech/tokenizer/moshi/sm.hpp" + +namespace emel::speech::tokenizer::moshi { + +using Tokenizer = sm; + +} // namespace emel::speech::tokenizer::moshi diff --git a/src/emel/speech/tokenizer/moshi/context.hpp b/src/emel/speech/tokenizer/moshi/context.hpp new file mode 100644 index 00000000..209cd881 --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/context.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace emel::speech::tokenizer::moshi { + +struct dependencies { + std::span delays = {}; + std::span cache = {}; + int32_t codebooks = 0; + int32_t generated_audio_codebooks = 0; + int32_t delayed_audio_codebooks = 0; + int32_t cache_rows = 0; + int32_t maximum_delay = 0; + int32_t initial_delay_frames = 0; + int32_t text_initial_token = 0; + int32_t audio_initial_token = 0; + int32_t token_zero = 0; + int32_t token_ungenerated = 0; +}; + +namespace action { + +struct context { + explicit context(const dependencies &deps) noexcept : config(deps) {} + + const dependencies config; + int64_t offset = 0; +}; + +} // namespace action + +} // namespace emel::speech::tokenizer::moshi diff --git a/src/emel/speech/tokenizer/moshi/detail.hpp b/src/emel/speech/tokenizer/moshi/detail.hpp new file mode 100644 index 00000000..b3dc5e31 --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/detail.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +#include "emel/speech/tokenizer/moshi/context.hpp" +#include "emel/speech/tokenizer/moshi/events.hpp" + +namespace emel::speech::tokenizer::moshi::detail { + +inline int32_t compute_cache_row(const action::context &ctx, + const int64_t offset) noexcept { + const int64_t rows = ctx.config.cache_rows; + const int64_t position = offset % rows; + return static_cast(position + ((position < 0) * rows)); +} + +inline int32_t &cache_at(action::context &ctx, const int32_t row, + const int32_t codebook) noexcept { + return ctx.config.cache[static_cast(row) * + static_cast(ctx.config.codebooks) + + static_cast(codebook)]; +} + +inline int32_t cache_at(const action::context &ctx, const int32_t row, + const int32_t codebook) noexcept { + return ctx.config.cache[static_cast(row) * + static_cast(ctx.config.codebooks) + + static_cast(codebook)]; +} + +inline void compute_model_tokens(const event::tokenize &ev, + const action::context &ctx) noexcept { + const int32_t row = compute_cache_row(ctx, ctx.offset); + const int32_t text_initial_lane = static_cast( + ctx.offset <= static_cast(ctx.config.delays[0])); + const int32_t text_cache_lane = 1 - text_initial_lane; + ev.model_tokens_out[0] = text_initial_lane * ctx.config.text_initial_token + + text_cache_lane * cache_at(ctx, row, 0); + + for (int32_t codebook = 1; codebook < ctx.config.codebooks; ++codebook) { + const int32_t initial_lane = static_cast( + ctx.offset <= static_cast(ctx.config.delays[codebook])); + const int32_t cache_lane = 1 - initial_lane; + ev.model_tokens_out[static_cast(codebook)] = + initial_lane * ctx.config.audio_initial_token + + cache_lane * cache_at(ctx, row, codebook); + } +} + +} // namespace emel::speech::tokenizer::moshi::detail diff --git a/src/emel/speech/tokenizer/moshi/errors.hpp b/src/emel/speech/tokenizer/moshi/errors.hpp new file mode 100644 index 00000000..eb3521ef --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/errors.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "emel/error/error.hpp" + +namespace emel::speech::tokenizer::moshi { + +enum class error : emel::error::type { + none = 0u, + invalid_configuration = (1u << 0), + uninitialized = (1u << 1), + already_initialized = (1u << 2), + request_shape = (1u << 3), + phase_order = (1u << 4), + position_overflow = (1u << 5), + internal_error = (1u << 6), +}; + +} // namespace emel::speech::tokenizer::moshi diff --git a/src/emel/speech/tokenizer/moshi/events.hpp b/src/emel/speech/tokenizer/moshi/events.hpp new file mode 100644 index 00000000..0cf0d026 --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/events.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +namespace emel::speech::tokenizer::moshi::event { + +struct initialize { + int32_t &error_out; +}; + +struct tokenize { + std::span audio_tokens = {}; + std::span model_tokens_out = {}; + int32_t &error_out; +}; + +struct detokenize { + int32_t text_token; + std::span audio_tokens; + int32_t &text_token_out; + std::span audio_tokens_out; + bool &produced_out; + int32_t &error_out; +}; + +struct restore_cache { + std::span column_major_cache; + int64_t offset; + int32_t &error_out; +}; + +struct advance { + int32_t &error_out; +}; + +struct reset { + int32_t &error_out; +}; + +struct detokenize_ctx { + int64_t source_offset = 0; +}; + +struct detokenize_run { + const detokenize &request; + detokenize_ctx &ctx; +}; + +} // namespace emel::speech::tokenizer::moshi::event diff --git a/src/emel/speech/tokenizer/moshi/guards.hpp b/src/emel/speech/tokenizer/moshi/guards.hpp new file mode 100644 index 00000000..2fc036ba --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/guards.hpp @@ -0,0 +1,283 @@ +#pragma once + +#include +#include +#include + +#include "emel/speech/tokenizer/moshi/context.hpp" +#include "emel/speech/tokenizer/moshi/events.hpp" + +namespace emel::speech::tokenizer::moshi::guard { + +struct guard_configuration_valid { + bool operator()(const event::initialize &, + const action::context &ctx) const noexcept { + const auto &config = ctx.config; + if (config.codebooks <= 1 || config.generated_audio_codebooks <= 0 || + config.generated_audio_codebooks >= config.codebooks || + config.delayed_audio_codebooks <= 0 || + config.delayed_audio_codebooks > config.generated_audio_codebooks || + config.cache_rows <= 0 || config.maximum_delay < 0 || + config.initial_delay_frames < 0 || + config.token_zero == config.token_ungenerated || + config.delays.size() < static_cast(config.codebooks)) { + return false; + } + const int32_t needed = + config.codebooks - config.delayed_audio_codebooks - 1; + if (needed < 0 || static_cast(config.cache_rows) < + static_cast(config.maximum_delay) + 2) { + return false; + } + const uint64_t elements = static_cast(config.cache_rows) * + static_cast(config.codebooks); + if (elements > config.cache.size()) { + return false; + } + int32_t observed_maximum = 0; + for (int32_t codebook = 0; codebook < config.codebooks; ++codebook) { + const int32_t delay = config.delays[static_cast(codebook)]; + if (delay < 0 || delay > config.maximum_delay) { + return false; + } + if (delay > observed_maximum) { + observed_maximum = delay; + } + } + return observed_maximum == config.maximum_delay; + } +}; + +struct guard_configuration_invalid { + bool operator()(const event::initialize &ev, + const action::context &ctx) const noexcept { + return !guard_configuration_valid{}(ev, ctx); + } +}; + +struct guard_tokenize_output_valid { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return ev.model_tokens_out.size() == + static_cast(ctx.config.codebooks); + } +}; + +struct guard_tokenize_position_available { + bool operator()(const event::tokenize &, + const action::context &ctx) const noexcept { + return ctx.offset <= std::numeric_limits::max() - + static_cast(ctx.config.maximum_delay); + } +}; + +struct guard_tokenize_full_shape { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return guard_tokenize_output_valid{}(ev, ctx) && + ev.audio_tokens.size() == static_cast(ctx.config.codebooks); + } +}; + +struct guard_tokenize_tail_shape { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + const int32_t needed = + ctx.config.codebooks - ctx.config.delayed_audio_codebooks - 1; + return guard_tokenize_output_valid{}(ev, ctx) && needed > 0 && + ev.audio_tokens.size() == static_cast(needed); + } +}; + +struct guard_tokenize_empty_shape { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + const int32_t needed = + ctx.config.codebooks - ctx.config.delayed_audio_codebooks - 1; + return guard_tokenize_output_valid{}(ev, ctx) && needed == 0 && + ev.audio_tokens.empty(); + } +}; + +struct guard_tokenize_shape_valid { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return guard_tokenize_full_shape{}(ev, ctx) || + guard_tokenize_tail_shape{}(ev, ctx) || + guard_tokenize_empty_shape{}(ev, ctx); + } +}; + +struct guard_tokenize_full { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return guard_tokenize_full_shape{}(ev, ctx) && + guard_tokenize_position_available{}(ev, ctx); + } +}; + +struct guard_tokenize_tail { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return guard_tokenize_tail_shape{}(ev, ctx) && + guard_tokenize_position_available{}(ev, ctx); + } +}; + +struct guard_tokenize_empty { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return guard_tokenize_empty_shape{}(ev, ctx) && + guard_tokenize_position_available{}(ev, ctx); + } +}; + +struct guard_tokenize_invalid { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return !guard_tokenize_shape_valid{}(ev, ctx); + } +}; + +struct guard_tokenize_position_overflow { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + return guard_tokenize_shape_valid{}(ev, ctx) && + !guard_tokenize_position_available{}(ev, ctx); + } +}; + +struct guard_restore_valid { + bool operator()(const event::restore_cache &ev, + const action::context &ctx) const noexcept { + const uint64_t elements = static_cast(ctx.config.cache_rows) * + static_cast(ctx.config.codebooks); + return elements == ev.column_major_cache.size() && ev.offset >= 0 && + ev.offset <= std::numeric_limits::max() - + static_cast(ctx.config.maximum_delay); + } +}; + +struct guard_advance_position_available { + bool operator()(const event::advance &, + const action::context &ctx) const noexcept { + return ctx.offset < std::numeric_limits::max(); + } +}; + +struct guard_advance_position_overflow { + bool operator()(const event::advance &ev, + const action::context &ctx) const noexcept { + return !guard_advance_position_available{}(ev, ctx); + } +}; + +struct guard_restore_invalid { + bool operator()(const event::restore_cache &ev, + const action::context &ctx) const noexcept { + return !guard_restore_valid{}(ev, ctx); + } +}; + +struct guard_detokenize_shape_valid { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.request.audio_tokens.size() == + static_cast(ctx.config.generated_audio_codebooks) && + runtime_ev.request.audio_tokens_out.size() == + static_cast(ctx.config.delayed_audio_codebooks); + } +}; + +struct guard_detokenize_shape_invalid { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_detokenize_shape_valid{}(runtime_ev, ctx); + } +}; + +struct guard_position_available { + bool operator()(const event::detokenize_run &, + const action::context &ctx) const noexcept { + return ctx.offset < std::numeric_limits::max(); + } +}; + +struct guard_position_overflow { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_detokenize_shape_valid{}(runtime_ev, ctx) && + !guard_position_available{}(runtime_ev, ctx); + } +}; + +struct guard_replace_generated_audio { + bool operator()(const event::detokenize_run &, + const action::context &ctx) const noexcept { + return ctx.config.initial_delay_frames > 0 && + ctx.offset < ctx.config.initial_delay_frames; + } +}; + +struct guard_use_generated_audio { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_replace_generated_audio{}(runtime_ev, ctx); + } +}; + +struct guard_detokenize_valid_replace { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_detokenize_shape_valid{}(runtime_ev, ctx) && + guard_position_available{}(runtime_ev, ctx) && + guard_replace_generated_audio{}(runtime_ev, ctx); + } +}; + +struct guard_detokenize_valid_generated { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_detokenize_shape_valid{}(runtime_ev, ctx) && + guard_position_available{}(runtime_ev, ctx) && + guard_use_generated_audio{}(runtime_ev, ctx); + } +}; + +struct guard_before_output_delay { + bool operator()(const event::detokenize_run &, + const action::context &ctx) const noexcept { + return ctx.offset <= ctx.config.maximum_delay; + } +}; + +struct guard_past_output_delay { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_before_output_delay{}(runtime_ev, ctx); + } +}; + +struct guard_output_incomplete { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + bool incomplete = false; + for (int32_t codebook = 0; codebook < ctx.config.delayed_audio_codebooks; + ++codebook) { + if (runtime_ev.request.audio_tokens_out[static_cast(codebook)] == + ctx.config.token_zero) { + incomplete = true; + } + } + return incomplete; + } +}; + +struct guard_output_complete { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_output_incomplete{}(runtime_ev, ctx); + } +}; + +} // namespace emel::speech::tokenizer::moshi::guard diff --git a/src/emel/speech/tokenizer/moshi/sm.hpp b/src/emel/speech/tokenizer/moshi/sm.hpp new file mode 100644 index 00000000..0123320a --- /dev/null +++ b/src/emel/speech/tokenizer/moshi/sm.hpp @@ -0,0 +1,275 @@ +#pragma once + +// benchmark: designed + +#include + +#include "emel/sm.hpp" +#include "emel/speech/tokenizer/moshi/actions.hpp" +#include "emel/speech/tokenizer/moshi/context.hpp" +#include "emel/speech/tokenizer/moshi/events.hpp" +#include "emel/speech/tokenizer/moshi/guards.hpp" + +namespace emel::speech::tokenizer::moshi { + +struct state_uninitialized {}; +struct state_ready {}; +struct state_prepared_full {}; +struct state_prepared_generated {}; +struct state_commit_full_zero {}; +struct state_commit_full_generated {}; +struct state_commit_generated_zero {}; +struct state_commit_generated {}; +struct state_output_decision {}; +struct state_output_validation {}; +struct state_errored {}; + +/* +Moshi tokenizer architecture notes (single source of truth) + +state purpose +- state_ready accepts the first half of a frame and tokenizes the caller's + audio codebooks into the delay-aligned LM input sequence. +- state_prepared_full records that all codebooks were provided, while + state_prepared_generated records tail-only or generator-owned input. The + state graph therefore owns cache-write policy without a persistent flag. +- commit states select initial-delay replacement and provided-cache + preservation before executing fixed data-plane cache writes. + +control invariants +- delay geometry, token sentinels, and cache storage are injected; the actor + owns no global limits and allocates nothing during construction or dispatch. +- tokenize and detokenize must alternate. Phase-order, shape, overflow, + initialization, and restore failures are explicit transitions. +- context contains only the persistent frame offset and injected storage. + Per-dispatch source offsets travel through the typed detokenize_run event. + +guard semantics and action side effects +- configuration guards validate every injected extent and delay before the + cache is initialized. +- tokenize guards select full, tail, or empty input shapes; their actions write + delayed inputs and publish one model-token frame. +- detokenize guards select generated versus zero audio and overflow outcomes; + commit actions advance once, update the ring, and output actions reverse the + codebook delay pattern. +*/ +struct model { + auto operator()() const { + namespace sml = stateforward::sml; + + using effect_commit_full_zero = action::effect_commit_generated< + action::cache_write_mode::preserve_provided, + action::audio_write_mode::zero>; + using effect_commit_full_generated = action::effect_commit_generated< + action::cache_write_mode::preserve_provided, + action::audio_write_mode::generated>; + using effect_commit_zero = + action::effect_commit_generated; + using effect_commit_generated = + action::effect_commit_generated; + + // clang-format off + return sml::make_transition_table( + //------------------------------------------------------------------------------// + // Initialization and recovery validate only injected geometry. + sml::state <= *sml::state + + sml::event [ guard::guard_configuration_valid{} ] + / action::effect_initialize{} + , sml::state <= sml::state + + sml::event [ guard::guard_configuration_invalid{} ] + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event [ guard::guard_configuration_valid{} ] + / action::effect_initialize{} + , sml::state <= sml::state + + sml::event [ guard::guard_configuration_invalid{} ] + / action::effect_reject{} + + //------------------------------------------------------------------------------// + // Tokenization writes delayed caller input and records the cache policy + // for the matching detokenize dispatch in state. + , sml::state <= sml::state + + sml::event [ guard::guard_tokenize_full{} ] + / action::effect_tokenize_full{} + , sml::state <= sml::state + + sml::event [ guard::guard_tokenize_tail{} ] + / action::effect_tokenize_tail{} + , sml::state <= sml::state + + sml::event [ guard::guard_tokenize_empty{} ] + / action::effect_tokenize_empty{} + , sml::state <= sml::state + + sml::event [ guard::guard_tokenize_invalid{} ] + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + [ guard::guard_tokenize_position_overflow{} ] + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + + //------------------------------------------------------------------------------// + // Detokenization explicitly selects full-input preservation and initial + // delay replacement before the fixed commit action executes. + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_valid_replace{} ] + / action::effect_begin_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_valid_generated{} ] + / action::effect_begin_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_valid_replace{} ] + / action::effect_begin_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_valid_generated{} ] + / action::effect_begin_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_shape_invalid{} ] + / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_shape_invalid{} ] + / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event [ guard::guard_position_overflow{} ] + / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event [ guard::guard_position_overflow{} ] + / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::completion / effect_commit_full_zero{} + , sml::state <= sml::state + + sml::completion / effect_commit_full_generated{} + , sml::state <= sml::state + + sml::completion / effect_commit_zero{} + , sml::state <= sml::state + + sml::completion / effect_commit_generated{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_before_output_delay{} ] / action::effect_publish_no_output{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_past_output_delay{} ] / action::effect_collect_output{} + , sml::state <= sml::state + + sml::completion [ guard::guard_output_complete{} ] + / action::effect_publish_output{} + , sml::state <= sml::state + + sml::completion [ guard::guard_output_incomplete{} ] + / action::effect_publish_no_output{} + + //------------------------------------------------------------------------------// + // Cache restore and sequence reset preserve injected geometry. + , sml::state <= sml::state + + sml::event [ guard::guard_restore_valid{} ] + / action::effect_restore_column_major_cache{} + , sml::state <= sml::state + + sml::event [ guard::guard_restore_invalid{} ] + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event + [ guard::guard_advance_position_available{} ] / action::effect_advance{} + , sml::state <= sml::state + + sml::event + [ guard::guard_advance_position_overflow{} ] + / action::effect_reject{} + , sml::state <= sml::state + + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} + + //------------------------------------------------------------------------------// + // Known operations outside their legal phase are explicit. + , sml::state <= sml::state + + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + , sml::state <= sml::state + + sml::event / action::effect_reject{} + + //------------------------------------------------------------------------------// + // Unknown external events make the actor observably errored. + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + ); + // clang-format on + } +}; + +struct sm : public emel::sm { + using base_type = emel::sm; + using base_type::is; + using base_type::process_event; + using base_type::visit_current_states; + + explicit sm(const dependencies &deps) : base_type(std::in_place, deps) {} + + bool process_event(const event::detokenize &ev) { + event::detokenize_ctx ctx{}; + event::detokenize_run runtime_ev{ev, ctx}; + return base_type::process_event(runtime_ev); + } +}; + +using Moshi = sm; + +} // namespace emel::speech::tokenizer::moshi diff --git a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp new file mode 100644 index 00000000..2f4de334 --- /dev/null +++ b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp @@ -0,0 +1,352 @@ +#include +#include +#include +#include + +#include + +#include "../../../allocation_tracker.hpp" +#include "emel/error/error.hpp" +#include "emel/speech/tokenizer/moshi/sm.hpp" + +namespace { + +namespace moshi = emel::speech::tokenizer::moshi; +namespace sml = stateforward::sml; + +int32_t error_code(const moshi::error value) noexcept { + return static_cast(emel::error::cast(value)); +} + +struct standard_fixture { + static constexpr int32_t codebooks = 3; + static constexpr int32_t generated_codebooks = 2; + static constexpr int32_t delayed_codebooks = 2; + static constexpr int32_t rows = 4; + + explicit standard_fixture(const int32_t initial_delay_frames = 0) + : machine(moshi::dependencies{ + .delays = std::span{delays}, + .cache = std::span{cache}, + .codebooks = codebooks, + .generated_audio_codebooks = generated_codebooks, + .delayed_audio_codebooks = delayed_codebooks, + .cache_rows = rows, + .maximum_delay = 2, + .initial_delay_frames = initial_delay_frames, + .text_initial_token = 100, + .audio_initial_token = 200, + .token_zero = -1, + .token_ungenerated = -2, + }) {} + + bool initialize() { + err = error_code(moshi::error::none); + return machine.process_event(moshi::event::initialize{.error_out = err}); + } + + bool tokenize(const std::span input = {}) { + err = error_code(moshi::error::none); + return machine.process_event(moshi::event::tokenize{ + .audio_tokens = input, + .model_tokens_out = std::span{model_tokens}, + .error_out = err, + }); + } + + bool detokenize(const int32_t text, + const std::span generated) { + err = error_code(moshi::error::none); + return machine.process_event(moshi::event::detokenize{ + .text_token = text, + .audio_tokens = generated, + .text_token_out = text_out, + .audio_tokens_out = std::span{audio_out}, + .produced_out = produced, + .error_out = err, + }); + } + + std::array delays = {0, 1, 2}; + std::array cache = {}; + std::array model_tokens = {}; + std::array audio_out = {}; + int32_t text_out = -1; + bool produced = false; + int32_t err = error_code(moshi::error::none); + moshi::sm machine; +}; + +} // namespace + +TEST_CASE("speech Moshi tokenizer delays and restores codebook alignment") { + standard_fixture state; + REQUIRE(state.initialize()); + CHECK(state.machine.is(sml::state)); + + REQUIRE(state.tokenize()); + CHECK(state.model_tokens == std::array{100, 200, 200}); + const std::array first_audio = {11, 12}; + REQUIRE(state.detokenize(10, first_audio)); + CHECK_FALSE(state.produced); + + REQUIRE(state.tokenize()); + CHECK(state.model_tokens == std::array{10, 200, 200}); + const std::array second_audio = {21, 22}; + REQUIRE(state.detokenize(20, second_audio)); + CHECK_FALSE(state.produced); + + REQUIRE(state.tokenize()); + CHECK(state.model_tokens == std::array{20, 21, 200}); + const std::array third_audio = {31, 32}; + REQUIRE(state.detokenize(30, third_audio)); + CHECK(state.produced); + CHECK(state.text_out == 10); + CHECK(state.audio_out == std::array{21, 32}); +} + +TEST_CASE("speech Moshi tokenizer preserves complete provided frames") { + standard_fixture state; + REQUIRE(state.initialize()); + + const std::array first_input = {50, 51, 52}; + const std::array second_input = {60, 61, 62}; + const std::array third_input = {70, 71, 72}; + const std::array generated = {901, 902}; + + REQUIRE(state.tokenize(first_input)); + REQUIRE(state.detokenize(900, generated)); + REQUIRE(state.tokenize(second_input)); + REQUIRE(state.detokenize(900, generated)); + REQUIRE(state.tokenize(third_input)); + REQUIRE(state.detokenize(900, generated)); + + CHECK(state.produced); + CHECK(state.text_out == 60); + CHECK(state.audio_out == std::array{61, 62}); +} + +TEST_CASE("speech Moshi tokenizer accepts the PersonaPlex tail shape") { + std::array delays = {0, 1, 1, 1, 1}; + std::array cache = {}; + moshi::sm machine{moshi::dependencies{ + .delays = std::span{delays}, + .cache = std::span{cache}, + .codebooks = 5, + .generated_audio_codebooks = 4, + .delayed_audio_codebooks = 2, + .cache_rows = 4, + .maximum_delay = 1, + .initial_delay_frames = 0, + .text_initial_token = 100, + .audio_initial_token = 200, + .token_zero = -1, + .token_ungenerated = -2, + }}; + int32_t err = error_code(moshi::error::none); + REQUIRE(machine.process_event(moshi::event::initialize{.error_out = err})); + + std::array tail = {301, 302}; + std::array model_tokens = {}; + REQUIRE(machine.process_event(moshi::event::tokenize{ + .audio_tokens = std::span{tail}, + .model_tokens_out = std::span{model_tokens}, + .error_out = err, + })); + CHECK(model_tokens == std::array{100, 200, 200, 200, 200}); + + std::array generated = {11, 12, 13, 14}; + std::array output = {}; + int32_t text_out = -1; + bool produced = false; + REQUIRE(machine.process_event(moshi::event::detokenize{ + .text_token = 10, + .audio_tokens = std::span{generated}, + .text_token_out = text_out, + .audio_tokens_out = std::span{output}, + .produced_out = produced, + .error_out = err, + })); + CHECK_FALSE(produced); +} + +TEST_CASE("speech Moshi tokenizer masks initial delayed audio explicitly") { + standard_fixture state{2}; + REQUIRE(state.initialize()); + const std::array generated = {11, 12}; + + REQUIRE(state.tokenize()); + REQUIRE(state.detokenize(10, generated)); + CHECK_FALSE(state.produced); + REQUIRE(state.tokenize()); + REQUIRE(state.detokenize(20, generated)); + CHECK_FALSE(state.produced); + REQUIRE(state.tokenize()); + CHECK(state.model_tokens == std::array{20, -1, 200}); + REQUIRE(state.detokenize(30, generated)); + CHECK_FALSE(state.produced); +} + +TEST_CASE("speech Moshi tokenizer restores column-major voice cache") { + standard_fixture state; + REQUIRE(state.initialize()); + const std::array generated = {41, 42}; + REQUIRE(state.tokenize()); + REQUIRE(state.detokenize(40, generated)); + REQUIRE(state.tokenize()); + REQUIRE(state.detokenize(40, generated)); + + const std::array column_major = { + 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33, + }; + REQUIRE(state.machine.process_event(moshi::event::restore_cache{ + .column_major_cache = std::span{column_major}, + .offset = 2, + .error_out = state.err, + })); + + REQUIRE(state.tokenize()); + CHECK(state.model_tokens == std::array{12, 22, 200}); +} + +TEST_CASE("speech Moshi tokenizer advances a provided prompt frame") { + standard_fixture state; + REQUIRE(state.initialize()); + const std::array prompt = {50, 51, 52}; + REQUIRE(state.tokenize(prompt)); + REQUIRE(state.machine.process_event( + moshi::event::advance{.error_out = state.err})); + REQUIRE(state.tokenize()); + CHECK(state.model_tokens == std::array{-2, 200, 200}); +} + +TEST_CASE("speech Moshi tokenizer models lifecycle and shape failures") { + standard_fixture state; + std::array generated = {11, 12}; + + CHECK(state.tokenize()); + CHECK(state.err == error_code(moshi::error::uninitialized)); + REQUIRE(state.initialize()); + CHECK(state.initialize()); + CHECK(state.err == error_code(moshi::error::already_initialized)); + + std::array invalid_input = {1}; + CHECK(state.tokenize(invalid_input)); + CHECK(state.err == error_code(moshi::error::request_shape)); + REQUIRE(state.tokenize()); + + std::array invalid_generated = {1}; + CHECK(state.detokenize(10, invalid_generated)); + CHECK(state.err == error_code(moshi::error::request_shape)); + REQUIRE(state.detokenize(10, generated)); + + CHECK( + state.machine.process_event(moshi::event::reset{.error_out = state.err})); + CHECK(state.machine.is(sml::state)); +} + +TEST_CASE("speech Moshi tokenizer rejects invalid injected geometry") { + std::array delays = {0}; + std::array cache = {}; + moshi::sm machine{moshi::dependencies{ + .delays = std::span{delays}, + .cache = std::span{cache}, + .codebooks = 1, + .generated_audio_codebooks = 0, + .delayed_audio_codebooks = 0, + .cache_rows = 1, + .maximum_delay = 0, + .initial_delay_frames = 0, + .text_initial_token = 0, + .audio_initial_token = 0, + .token_zero = -1, + .token_ungenerated = -2, + }}; + int32_t err = error_code(moshi::error::none); + CHECK(machine.process_event(moshi::event::initialize{.error_out = err})); + CHECK(err == error_code(moshi::error::invalid_configuration)); + CHECK(machine.is(sml::state)); +} + +TEST_CASE("speech Moshi tokenizer dispatch remains allocation free") { + standard_fixture state; + REQUIRE(state.initialize()); + const std::array generated = {11, 12}; + + emel::test::allocation::allocation_scope allocations; + for (int32_t frame = 0; frame < 32; ++frame) { + REQUIRE(state.tokenize()); + REQUIRE(state.detokenize(frame, generated)); + } + CHECK(allocations.allocations() == 0u); +} + +TEST_CASE("speech Moshi tokenizer makes position overflow explicit") { + standard_fixture state; + REQUIRE(state.initialize()); + REQUIRE(state.tokenize()); + + moshi::action::context context{moshi::dependencies{ + .delays = std::span{state.delays}, + .cache = std::span{state.cache}, + .codebooks = standard_fixture::codebooks, + .generated_audio_codebooks = standard_fixture::generated_codebooks, + .delayed_audio_codebooks = standard_fixture::delayed_codebooks, + .cache_rows = standard_fixture::rows, + .maximum_delay = 2, + .initial_delay_frames = 0, + .text_initial_token = 100, + .audio_initial_token = 200, + .token_zero = -1, + .token_ungenerated = -2, + }}; + stateforward::sml::sm machine{ + context}; + machine.set_current_states(sml::state); + context.offset = std::numeric_limits::max(); + + std::array generated = {11, 12}; + std::array output = {}; + int32_t text_out = -1; + bool produced = false; + int32_t err = error_code(moshi::error::none); + moshi::event::detokenize_ctx detokenize_ctx{}; + CHECK(machine.process_event(moshi::event::detokenize_run{ + .request = + moshi::event::detokenize{ + .text_token = 10, + .audio_tokens = std::span{generated}, + .text_token_out = text_out, + .audio_tokens_out = std::span{output}, + .produced_out = produced, + .error_out = err, + }, + .ctx = detokenize_ctx, + })); + CHECK(err == error_code(moshi::error::position_overflow)); + + machine.set_current_states(sml::state); + std::array model_tokens = {}; + err = error_code(moshi::error::none); + CHECK(machine.process_event(moshi::event::tokenize{ + .audio_tokens = {}, + .model_tokens_out = std::span{model_tokens}, + .error_out = err, + })); + CHECK(err == error_code(moshi::error::position_overflow)); +} + +TEST_CASE("speech Moshi tokenizer exposes unexpected events and recovers") { + struct unknown_event {}; + + standard_fixture state; + REQUIRE(state.initialize()); + CHECK(state.machine.process_event(unknown_event{})); + CHECK(state.machine.is(sml::state)); + + CHECK(state.tokenize()); + CHECK(state.err == error_code(moshi::error::internal_error)); + REQUIRE( + state.machine.process_event(moshi::event::reset{.error_out = state.err})); + CHECK(state.machine.is(sml::state)); +} From 92893762358bf6051c6fb67e16a464c57c2d9008 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 17:02:48 -0500 Subject: [PATCH 10/61] refactor: scaffold generic speech generator --- .../architecture/mermaid/speech_generator.mmd | 62 ++++ .planning/architecture/speech_generator.md | 134 +++++++ CMakeLists.txt | 2 +- README.md | 1 + scripts/check_domain_boundaries.sh | 39 +- scripts/quality_gates.sh | 10 - scripts/test_with_coverage.sh | 6 - src/emel/generator/actions.hpp | 7 - src/emel/generator/context.hpp | 7 - src/emel/generator/detail.hpp | 7 - src/emel/generator/errors.hpp | 7 - src/emel/generator/events.hpp | 7 - src/emel/generator/guards.hpp | 7 - src/emel/generator/initializer/actions.hpp | 7 - src/emel/generator/initializer/context.hpp | 7 - src/emel/generator/initializer/detail.hpp | 7 - src/emel/generator/initializer/guards.hpp | 7 - src/emel/generator/initializer/sm.hpp | 7 - src/emel/generator/prefill/actions.hpp | 7 - src/emel/generator/prefill/context.hpp | 7 - src/emel/generator/prefill/detail.hpp | 7 - src/emel/generator/prefill/guards.hpp | 7 - src/emel/generator/prefill/sm.hpp | 7 - src/emel/generator/sm.hpp | 7 - src/emel/io/sm.hpp | 11 - src/emel/machines.hpp | 8 +- src/emel/speech/generator/actions.hpp | 144 ++++++++ src/emel/speech/generator/any.hpp | 9 + src/emel/speech/generator/context.hpp | 29 ++ src/emel/speech/generator/errors.hpp | 16 + src/emel/speech/generator/events.hpp | 166 +++++++++ src/emel/speech/generator/guards.hpp | 80 ++++ src/emel/speech/generator/sm.hpp | 346 ++++++++++++++++++ src/emel/text/encoders/sm.hpp | 79 ---- .../sortformer/request/lifecycle_tests.cpp | 5 - tests/io/loader/lifecycle_tests.cpp | 2 - tests/speech/generator/lifecycle_tests.cpp | 260 +++++++++++++ .../generator/legacy_compatibility_tests.cpp | 41 --- 38 files changed, 1268 insertions(+), 301 deletions(-) create mode 100644 .planning/architecture/mermaid/speech_generator.mmd create mode 100644 .planning/architecture/speech_generator.md delete mode 100644 src/emel/generator/actions.hpp delete mode 100644 src/emel/generator/context.hpp delete mode 100644 src/emel/generator/detail.hpp delete mode 100644 src/emel/generator/errors.hpp delete mode 100644 src/emel/generator/events.hpp delete mode 100644 src/emel/generator/guards.hpp delete mode 100644 src/emel/generator/initializer/actions.hpp delete mode 100644 src/emel/generator/initializer/context.hpp delete mode 100644 src/emel/generator/initializer/detail.hpp delete mode 100644 src/emel/generator/initializer/guards.hpp delete mode 100644 src/emel/generator/initializer/sm.hpp delete mode 100644 src/emel/generator/prefill/actions.hpp delete mode 100644 src/emel/generator/prefill/context.hpp delete mode 100644 src/emel/generator/prefill/detail.hpp delete mode 100644 src/emel/generator/prefill/guards.hpp delete mode 100644 src/emel/generator/prefill/sm.hpp delete mode 100644 src/emel/generator/sm.hpp delete mode 100644 src/emel/io/sm.hpp create mode 100644 src/emel/speech/generator/actions.hpp create mode 100644 src/emel/speech/generator/any.hpp create mode 100644 src/emel/speech/generator/context.hpp create mode 100644 src/emel/speech/generator/errors.hpp create mode 100644 src/emel/speech/generator/events.hpp create mode 100644 src/emel/speech/generator/guards.hpp create mode 100644 src/emel/speech/generator/sm.hpp delete mode 100644 src/emel/text/encoders/sm.hpp create mode 100644 tests/speech/generator/lifecycle_tests.cpp delete mode 100644 tests/text/generator/legacy_compatibility_tests.cpp diff --git a/.planning/architecture/mermaid/speech_generator.mmd b/.planning/architecture/mermaid/speech_generator.mmd new file mode 100644 index 00000000..ec3138f4 --- /dev/null +++ b/.planning/architecture/mermaid/speech_generator.mmd @@ -0,0 +1,62 @@ +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ + state_ready --> state_initialize_error_ready_channel_decision : initialize_run [always] / already_initialized__ + state_errored --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ + state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_present_] / effect_emit_initialize_done_ + state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_absent_] / none + state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ + state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / none + state_ready --> state_generate_conditioning : generate_run [guard_generate_request_valid_] / effect_prepare_generate_ + state_ready --> state_generate_error_ready_channel_decision : generate_run [guard_generate_request_invalid_] / invalid_request__ + state_generate_conditioning --> state_generate_prefill : completion_generate_run_ [always] / none + state_generate_prefill --> state_generate_predict : completion_generate_run_ [always] / none + state_generate_predict --> state_generate_sample : completion_generate_run_ [always] / none + state_generate_sample --> state_generate_decode : completion_generate_run_ [always] / none + state_generate_decode --> state_generate_postprocess : completion_generate_run_ [always] / none + state_generate_postprocess --> state_generate_error_ready_channel_decision : completion_generate_run_ [always] / cutover_pending__ + state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ + state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / none + state_ready --> state_stream_encode : stream_frame_run [guard_stream_request_valid_] / effect_prepare_stream_frame_ + state_ready --> state_stream_error_ready_channel_decision : stream_frame_run [guard_stream_request_invalid_] / invalid_request__ + state_stream_encode --> state_stream_tokenize : completion_stream_frame_run_ [always] / none + state_stream_tokenize --> state_stream_prefill : completion_stream_frame_run_ [always] / none + state_stream_prefill --> state_stream_predict : completion_stream_frame_run_ [always] / none + state_stream_predict --> state_stream_sample : completion_stream_frame_run_ [always] / none + state_stream_sample --> state_stream_detokenize : completion_stream_frame_run_ [always] / none + state_stream_detokenize --> state_stream_decode : completion_stream_frame_run_ [always] / none + state_stream_decode --> state_stream_postprocess : completion_stream_frame_run_ [always] / none + state_stream_postprocess --> state_stream_error_ready_channel_decision : completion_stream_frame_run_ [always] / cutover_pending__ + state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ + state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / none + state_ready --> state_flush_decode : flush_run [guard_flush_request_valid_] / effect_prepare_flush_ + state_ready --> state_flush_error_ready_channel_decision : flush_run [guard_flush_request_invalid_] / invalid_request__ + state_flush_decode --> state_flush_postprocess : completion_flush_run_ [always] / none + state_flush_postprocess --> state_flush_error_ready_channel_decision : completion_flush_run_ [always] / cutover_pending__ + state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ + state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / none + state_uninitialized --> state_generate_error_uninitialized_channel_decision : generate_run [always] / uninitialized__ + state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ + state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / none + state_uninitialized --> state_stream_error_uninitialized_channel_decision : stream_frame_run [always] / uninitialized__ + state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ + state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / none + state_uninitialized --> state_flush_error_uninitialized_channel_decision : flush_run [always] / uninitialized__ + state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ + state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / none + state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ + state_errored --> state_generate_error_errored_channel_decision : generate_run [always] / internal_error__ + state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ + state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / none + state_errored --> state_stream_error_errored_channel_decision : stream_frame_run [always] / internal_error__ + state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ + state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / none + state_errored --> state_flush_error_errored_channel_decision : flush_run [always] / internal_error__ + state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ + state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / none + state_ready --> state_ready : reset [always] / effect_reset_ + state_errored --> state_ready : reset [always] / effect_reset_ + state_uninitialized --> state_errored : _ [always] / effect_unexpected_ + state_ready --> state_errored : _ [always] / effect_unexpected_ + state_errored --> state_errored : _ [always] / effect_unexpected_ diff --git a/.planning/architecture/speech_generator.md b/.planning/architecture/speech_generator.md new file mode 100644 index 00000000..be28ddd5 --- /dev/null +++ b/.planning/architecture/speech_generator.md @@ -0,0 +1,134 @@ +# speech_generator + +Source: [`emel/speech/generator/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) + +## Mermaid + +```mermaid +stateDiagram-v2 + direction TB + [*] --> state_uninitialized + state_uninitialized --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ + state_ready --> state_initialize_error_ready_channel_decision : initialize_run [always] / already_initialized__ + state_errored --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ + state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_present_] / effect_emit_initialize_done_ + state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_absent_] / none + state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ + state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / none + state_ready --> state_generate_conditioning : generate_run [guard_generate_request_valid_] / effect_prepare_generate_ + state_ready --> state_generate_error_ready_channel_decision : generate_run [guard_generate_request_invalid_] / invalid_request__ + state_generate_conditioning --> state_generate_prefill : completion_generate_run_ [always] / none + state_generate_prefill --> state_generate_predict : completion_generate_run_ [always] / none + state_generate_predict --> state_generate_sample : completion_generate_run_ [always] / none + state_generate_sample --> state_generate_decode : completion_generate_run_ [always] / none + state_generate_decode --> state_generate_postprocess : completion_generate_run_ [always] / none + state_generate_postprocess --> state_generate_error_ready_channel_decision : completion_generate_run_ [always] / cutover_pending__ + state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ + state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / none + state_ready --> state_stream_encode : stream_frame_run [guard_stream_request_valid_] / effect_prepare_stream_frame_ + state_ready --> state_stream_error_ready_channel_decision : stream_frame_run [guard_stream_request_invalid_] / invalid_request__ + state_stream_encode --> state_stream_tokenize : completion_stream_frame_run_ [always] / none + state_stream_tokenize --> state_stream_prefill : completion_stream_frame_run_ [always] / none + state_stream_prefill --> state_stream_predict : completion_stream_frame_run_ [always] / none + state_stream_predict --> state_stream_sample : completion_stream_frame_run_ [always] / none + state_stream_sample --> state_stream_detokenize : completion_stream_frame_run_ [always] / none + state_stream_detokenize --> state_stream_decode : completion_stream_frame_run_ [always] / none + state_stream_decode --> state_stream_postprocess : completion_stream_frame_run_ [always] / none + state_stream_postprocess --> state_stream_error_ready_channel_decision : completion_stream_frame_run_ [always] / cutover_pending__ + state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ + state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / none + state_ready --> state_flush_decode : flush_run [guard_flush_request_valid_] / effect_prepare_flush_ + state_ready --> state_flush_error_ready_channel_decision : flush_run [guard_flush_request_invalid_] / invalid_request__ + state_flush_decode --> state_flush_postprocess : completion_flush_run_ [always] / none + state_flush_postprocess --> state_flush_error_ready_channel_decision : completion_flush_run_ [always] / cutover_pending__ + state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ + state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / none + state_uninitialized --> state_generate_error_uninitialized_channel_decision : generate_run [always] / uninitialized__ + state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ + state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / none + state_uninitialized --> state_stream_error_uninitialized_channel_decision : stream_frame_run [always] / uninitialized__ + state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ + state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / none + state_uninitialized --> state_flush_error_uninitialized_channel_decision : flush_run [always] / uninitialized__ + state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ + state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / none + state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ + state_errored --> state_generate_error_errored_channel_decision : generate_run [always] / internal_error__ + state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ + state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / none + state_errored --> state_stream_error_errored_channel_decision : stream_frame_run [always] / internal_error__ + state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ + state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / none + state_errored --> state_flush_error_errored_channel_decision : flush_run [always] / internal_error__ + state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ + state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / none + state_ready --> state_ready : reset [always] / effect_reset_ + state_errored --> state_ready : reset [always] / effect_reset_ + state_uninitialized --> state_errored : _ [always] / effect_unexpected_ + state_ready --> state_errored : _ [always] / effect_unexpected_ + state_errored --> state_errored : _ [always] / effect_unexpected_ +``` + +## Transitions + +| Source | Event | Guard | Action | Target | +| --- | --- | --- | --- | --- | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_accept_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_initialize_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_accept_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_initialize_done_callback_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_initialize_done_callback_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_initialize_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_initialize_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_generate_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_prepare_generate>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_conditioning`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_generate_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_conditioning`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`cutover_pending>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_generation_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_stream_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_prepare_stream_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_encode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_stream_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_encode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_detokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_detokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`cutover_pending>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_stream_frame_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_flush_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_prepare_flush>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_flush_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`cutover_pending>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_flush_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_generation_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_stream_frame_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_flush_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_generation_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_generate_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_stream_frame_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_stream_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_flush_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_flush_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | +| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f47cad3..e2ecb517 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,7 +169,6 @@ if(EMEL_ENABLE_TESTS) tests/gbnf/lexer_tests.cpp tests/gbnf/parser_tests.cpp tests/gbnf/sampler_tests.cpp - tests/text/generator/legacy_compatibility_tests.cpp tests/text/generator/lifecycle_tests.cpp tests/text/generator/action_guard_tests.cpp tests/text/generator/detail_tests.cpp @@ -189,6 +188,7 @@ if(EMEL_ENABLE_TESTS) tests/diarization/sortformer/transformer/lifecycle_tests.cpp tests/speech/codec/mimi_detail_tests.cpp tests/speech/codec/mimi_lifecycle_tests.cpp + tests/speech/generator/lifecycle_tests.cpp tests/speech/generator/moshi_lifecycle_tests.cpp tests/speech/generator/moshi_executor_streaming_tests.cpp tests/speech/generator/moshi_personaplex_session_tests.cpp diff --git a/README.md b/README.md index e89714e5..a463e027 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/speech_generator_moshi_executor.md`](.planning/architecture/speech_generator_moshi_executor.md) - [`.planning/architecture/speech_generator_moshi_personaplex_session.md`](.planning/architecture/speech_generator_moshi_personaplex_session.md) - [`.planning/architecture/speech_generator_moshi.md`](.planning/architecture/speech_generator_moshi.md) +- [`.planning/architecture/speech_generator.md`](.planning/architecture/speech_generator.md) - [`.planning/architecture/speech_tokenizer_moshi.md`](.planning/architecture/speech_tokenizer_moshi.md) - [`.planning/architecture/tensor_view.md`](.planning/architecture/tensor_view.md) - [`.planning/architecture/text_conditioner.md`](.planning/architecture/text_conditioner.md) diff --git a/scripts/check_domain_boundaries.sh b/scripts/check_domain_boundaries.sh index 0a8a3981..3be6d9d1 100755 --- a/scripts/check_domain_boundaries.sh +++ b/scripts/check_domain_boundaries.sh @@ -19,24 +19,6 @@ check_no_matches() { rm -f /tmp/emel_domain_boundary_matches.$$ } -check_no_matches_except() { - local label="$1" - local pattern="$2" - local allow_pattern="$3" - shift 3 - - if rg -n "$pattern" "$@" >/tmp/emel_domain_boundary_matches.$$ 2>/dev/null; then - if grep -Ev "$allow_pattern" /tmp/emel_domain_boundary_matches.$$ \ - >/tmp/emel_domain_boundary_filtered.$$; then - echo "error: domain boundary leak: ${label}" >&2 - cat /tmp/emel_domain_boundary_filtered.$$ >&2 - status=1 - fi - rm -f /tmp/emel_domain_boundary_filtered.$$ - fi - rm -f /tmp/emel_domain_boundary_matches.$$ -} - check_absent_path() { local label="$1" shift @@ -74,10 +56,19 @@ check_no_matches "lfm2 model code depends on sibling model-family detail" \ 'emel/model/llama/(detail|any)\.hpp|emel/model/(qwen3|gemma4)/detail\.hpp|emel::model::llama::|emel::model::(qwen3|gemma4)::detail::' \ src/emel/model/lfm2 -check_no_matches_except "legacy text generator root" \ - 'emel/generator|emel::generator|namespace emel::generator|src/emel/generator|tests/generator' \ - '^(src/emel/generator/|tests/text/generator/legacy_compatibility_tests\.cpp:[0-9]+:|scripts/(quality_gates|test_with_coverage)\.sh:[0-9]+:.*src/emel/generator)' \ - src tests tools scripts/quality_gates.sh scripts/test_with_coverage.sh CMakeLists.txt +check_absent_path "legacy text generator root" \ + src/emel/generator tests/text/generator/legacy_compatibility_tests.cpp + +check_no_matches "legacy text generator includes or namespace" \ + 'emel/generator|emel::generator|namespace emel::generator|tests/generator' \ + src tests tools CMakeLists.txt + +check_absent_path "legacy generic machine aliases" \ + src/emel/io/sm.hpp src/emel/text/encoders/sm.hpp + +check_no_matches "legacy top-level machine aliases" \ + 'using[[:space:]]+(ComputeExecutor|DiarizationRequest|Model)[[:space:]]*=' \ + src tests tools CMakeLists.txt check_no_matches "text generator actor internals in maintained generation parity/benchmark lanes" \ 'emel/text/generator/(detail|actions|guards)\.hpp|emel::text::generator::(detail|action|guard)::|emel::text::generator::prefill::guard::|generation_internal_diagnostics' \ @@ -192,6 +183,10 @@ check_no_matches "Moshi/Mimi leaked into generic speech recognizer" \ 'moshi|model/moshi|model::moshi|tokenizer::moshi|codec::mimi|speech/codec/mimi' \ src/emel/speech/recognizer tests/speech/recognizer +check_no_matches "model-family names leaked into generic speech generator" \ + '[Mm]oshi|[Mm]imi|[Pp]ersona[Pp]lex|[Cc]hatterbox' \ + src/emel/speech/generator/*.hpp tests/speech/generator/lifecycle_tests.cpp + check_absent_path "retired generic diarization request owner path" \ src/emel/diarization/request \ tests/diarization/request \ diff --git a/scripts/quality_gates.sh b/scripts/quality_gates.sh index 19de3ef7..48bec0f0 100755 --- a/scripts/quality_gates.sh +++ b/scripts/quality_gates.sh @@ -234,9 +234,6 @@ run_sml_surface_gate() { is_coverage_excluded_src_file() { local file="$1" case "$file" in - src/emel/generator/*.hpp|src/emel/generator/**/*.hpp) - return 0 - ;; src/emel/*/sm.hpp|src/emel/**/*/sm.hpp) return 0 ;; @@ -329,9 +326,6 @@ infer_test_shard_for_src() { src/emel/model/*|src/emel/model*.hpp|src/emel/gguf/*|src/emel/gbnf/*|src/emel/batch/*) add_test_shard model_and_batch ;; - src/emel/generator/*|src/emel/generator/**/*) - add_test_shard generator_and_runtime - ;; src/emel/text/generator/*|src/emel/embeddings/*|src/emel/logits/*|src/emel/token/*) add_test_shard generator_and_runtime ;; @@ -797,8 +791,6 @@ infer_quality_gate_scope() { add_all_benchmark_suites_from_manifest fi ;; - src/emel/generator/*|src/emel/generator/**/*) - ;; docs/templates/*|tools/docsgen/*|snapshots/bench/*|snapshots/embedded_size/*|src/emel/**/sm.hpp) docs_needed=true ;; @@ -844,8 +836,6 @@ infer_quality_gate_scope() { fi case "$file" in - src/emel/generator/*|src/emel/generator/**/*) - ;; src/emel/diarization/*|src/emel/model/sortformer/*|tests/diarization/*|\ tools/bench/diarization*|scripts/bench_diarization_compare.sh|\ scripts/setup_diarization_pytorch_ref_env.sh) diff --git a/scripts/test_with_coverage.sh b/scripts/test_with_coverage.sh index d0593a2b..6ea51ba5 100755 --- a/scripts/test_with_coverage.sh +++ b/scripts/test_with_coverage.sh @@ -71,9 +71,6 @@ coverage_base_ref_resolved="$COVERAGE_BASE_REF" is_coverage_excluded_src_file() { local file="$1" case "$file" in - src/emel/generator/*.hpp|src/emel/generator/**/*.hpp) - return 0 - ;; src/emel/*/sm.hpp) return 0 ;; @@ -229,9 +226,6 @@ if [[ "$COVERAGE_CHANGED_ONLY" == "1" ]]; then src/emel/model/*|src/emel/model*.hpp|src/emel/gguf/*|src/emel/gbnf/*|src/emel/batch/*) add_changed_shard model_and_batch ;; - src/emel/generator/*|src/emel/generator/**/*) - add_changed_shard generator_and_runtime - ;; src/emel/text/generator/*|src/emel/embeddings/*|src/emel/logits/*|src/emel/token/*) add_changed_shard generator_and_runtime ;; diff --git a/src/emel/generator/actions.hpp b/src/emel/generator/actions.hpp deleted file mode 100644 index 392cf7cf..00000000 --- a/src/emel/generator/actions.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/actions.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/context.hpp b/src/emel/generator/context.hpp deleted file mode 100644 index 010f1c74..00000000 --- a/src/emel/generator/context.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/context.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/detail.hpp b/src/emel/generator/detail.hpp deleted file mode 100644 index 6baf45e7..00000000 --- a/src/emel/generator/detail.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/detail.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/errors.hpp b/src/emel/generator/errors.hpp deleted file mode 100644 index 99962e4f..00000000 --- a/src/emel/generator/errors.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/errors.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/events.hpp b/src/emel/generator/events.hpp deleted file mode 100644 index 88815df2..00000000 --- a/src/emel/generator/events.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/events.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/guards.hpp b/src/emel/generator/guards.hpp deleted file mode 100644 index ef3e799c..00000000 --- a/src/emel/generator/guards.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/guards.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/initializer/actions.hpp b/src/emel/generator/initializer/actions.hpp deleted file mode 100644 index 9474c56c..00000000 --- a/src/emel/generator/initializer/actions.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/initializer/actions.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/initializer/context.hpp b/src/emel/generator/initializer/context.hpp deleted file mode 100644 index fa1b2648..00000000 --- a/src/emel/generator/initializer/context.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/initializer/context.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/initializer/detail.hpp b/src/emel/generator/initializer/detail.hpp deleted file mode 100644 index 7bbfb3be..00000000 --- a/src/emel/generator/initializer/detail.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/initializer/detail.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/initializer/guards.hpp b/src/emel/generator/initializer/guards.hpp deleted file mode 100644 index 80da3667..00000000 --- a/src/emel/generator/initializer/guards.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/initializer/guards.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/initializer/sm.hpp b/src/emel/generator/initializer/sm.hpp deleted file mode 100644 index fe555942..00000000 --- a/src/emel/generator/initializer/sm.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/initializer/sm.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/prefill/actions.hpp b/src/emel/generator/prefill/actions.hpp deleted file mode 100644 index bd48bc33..00000000 --- a/src/emel/generator/prefill/actions.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/prefill/actions.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/prefill/context.hpp b/src/emel/generator/prefill/context.hpp deleted file mode 100644 index 91a2f945..00000000 --- a/src/emel/generator/prefill/context.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/prefill/context.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/prefill/detail.hpp b/src/emel/generator/prefill/detail.hpp deleted file mode 100644 index ff22659c..00000000 --- a/src/emel/generator/prefill/detail.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/prefill/detail.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/prefill/guards.hpp b/src/emel/generator/prefill/guards.hpp deleted file mode 100644 index a07ce77c..00000000 --- a/src/emel/generator/prefill/guards.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/prefill/guards.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/prefill/sm.hpp b/src/emel/generator/prefill/sm.hpp deleted file mode 100644 index 1b0bc029..00000000 --- a/src/emel/generator/prefill/sm.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/prefill/sm.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/generator/sm.hpp b/src/emel/generator/sm.hpp deleted file mode 100644 index 068dc810..00000000 --- a/src/emel/generator/sm.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "emel/text/generator/sm.hpp" - -namespace emel { -namespace generator = text::generator; -} // namespace emel diff --git a/src/emel/io/sm.hpp b/src/emel/io/sm.hpp deleted file mode 100644 index e83be647..00000000 --- a/src/emel/io/sm.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -// benchmark: designed - -#include "emel/io/loader/sm.hpp" - -namespace emel::io { - -using sm = emel::io::loader::sm; - -} // namespace emel::io diff --git a/src/emel/machines.hpp b/src/emel/machines.hpp index a9f3cf40..ebba237f 100644 --- a/src/emel/machines.hpp +++ b/src/emel/machines.hpp @@ -8,9 +8,9 @@ #include "emel/embeddings/generator/sm.hpp" #include "emel/gguf/loader/sm.hpp" #include "emel/graph/processor/sm.hpp" +#include "emel/io/loader/sm.hpp" #include "emel/io/mmap/sm.hpp" #include "emel/io/read/sm.hpp" -#include "emel/io/sm.hpp" #include "emel/io/staged_read/sm.hpp" #include "emel/memory/hybrid/sm.hpp" #include "emel/memory/kv/sm.hpp" @@ -19,26 +19,25 @@ #include "emel/model/loader/sm.hpp" #include "emel/model/tensor/sm.hpp" #include "emel/speech/codec/mimi/sm.hpp" +#include "emel/speech/generator/sm.hpp" #include "emel/text/conditioner/sm.hpp" #include "emel/text/detokenizer/sm.hpp" #include "emel/text/encoders/any.hpp" -#include "emel/text/encoders/sm.hpp" #include "emel/text/generator/sm.hpp" #include "emel/text/renderer/sm.hpp" #include "emel/text/tokenizer/sm.hpp" namespace emel { -using ComputeExecutor = emel::graph::processor::sm; using Conditioner = emel::text::conditioner::sm; using Detokenizer = emel::text::detokenizer::sm; using SortformerRequest = emel::diarization::sortformer::request::sm; -using DiarizationRequest = SortformerRequest; using SortformerExecutor = emel::diarization::sortformer::executor::sm; using SortformerPipeline = emel::diarization::sortformer::pipeline::sm; using OmniEmbedEmbeddingsGenerator = emel::embeddings::generator::omniembed::sm; using EmbeddingsGenerator = emel::embeddings::generator::sm; using MimiCodec = emel::speech::codec::mimi::sm; +using SpeechGenerator = emel::speech::generator::sm; using EncoderAny = emel::text::encoders::any; using EncoderBpe = emel::text::encoders::bpe::sm; using EncoderSpm = emel::text::encoders::spm::sm; @@ -57,7 +56,6 @@ using KvCache = emel::memory::kv::sm; using MemoryRecurrent = emel::memory::recurrent::sm; using MemoryStreaming = emel::memory::streaming::sm; using ModelLoader = emel::model::loader::sm; -using Model = emel::model::loader::sm; using Parser = emel::gguf::loader::sm; using Renderer = emel::text::renderer::sm; using Tokenizer = emel::text::tokenizer::sm; diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp new file mode 100644 index 00000000..dfe0f985 --- /dev/null +++ b/src/emel/speech/generator/actions.hpp @@ -0,0 +1,144 @@ +#pragma once + +#include "emel/error/error.hpp" +#include "emel/speech/generator/context.hpp" +#include "emel/speech/generator/errors.hpp" +#include "emel/speech/generator/events.hpp" + +namespace emel::speech::generator::action { + +inline emel::error::type error_code(const error value) noexcept { + return emel::error::cast(value); +} + +struct effect_accept_initialize { + void operator()(const event::initialize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.ctx.err = error_code(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_fail_initialize { + void operator()(const event::initialize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.ctx.err = error_code(error_value); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_prepare_generate { + void operator()(const event::generate_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = 0; + runtime_ev.ctx.err = error_code(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_fail_generate { + void operator()(const event::generate_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = 0; + runtime_ev.ctx.err = error_code(error_value); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_prepare_stream_frame { + void operator()(const event::stream_frame_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = 0; + runtime_ev.request.produced_out = false; + runtime_ev.ctx.err = error_code(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_fail_stream_frame { + void operator()(const event::stream_frame_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = 0; + runtime_ev.request.produced_out = false; + runtime_ev.ctx.err = error_code(error_value); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_prepare_flush { + void operator()(const event::flush_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = 0; + runtime_ev.request.complete_out = false; + runtime_ev.ctx.err = error_code(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_fail_flush { + void operator()(const event::flush_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = 0; + runtime_ev.request.complete_out = false; + runtime_ev.ctx.err = error_code(error_value); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +struct effect_emit_initialize_done { + void operator()(const event::initialize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_done(events::initialize_done{runtime_ev.request}); + } +}; + +struct effect_emit_initialize_error { + void operator()(const event::initialize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::initialize_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +struct effect_emit_generation_error { + void operator()(const event::generate_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::generation_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +struct effect_emit_stream_frame_error { + void operator()(const event::stream_frame_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::stream_frame_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +struct effect_emit_flush_error { + void operator()(const event::flush_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::flush_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +struct effect_reset { + void operator()(const event::reset &ev, const context &) const noexcept { + ev.error_out = error_code(error::none); + } +}; + +template struct effect_reject { + void operator()(const event::reset &ev, const context &) const noexcept { + ev.error_out = error_code(error_value); + } +}; + +struct effect_unexpected { + template + void operator()(const event_type &, const context &) const noexcept {} +}; + +} // namespace emel::speech::generator::action diff --git a/src/emel/speech/generator/any.hpp b/src/emel/speech/generator/any.hpp new file mode 100644 index 00000000..e3402025 --- /dev/null +++ b/src/emel/speech/generator/any.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "emel/speech/generator/sm.hpp" + +namespace emel::speech::generator { + +using SpeechGenerator = sm; + +} // namespace emel::speech::generator diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp new file mode 100644 index 00000000..8f2e45aa --- /dev/null +++ b/src/emel/speech/generator/context.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "emel/batch/planner/sm.hpp" +#include "emel/graph/sm.hpp" +#include "emel/kernel/sm.hpp" +#include "emel/logits/sampler/sm.hpp" +#include "emel/memory/hybrid/sm.hpp" + +namespace emel::speech::generator { + +struct dependencies { + emel::batch::planner::sm &planner; + emel::memory::hybrid::sm &memory; + emel::graph::sm &graph; + emel::logits::sampler::sm &sampler; + emel::kernel::sm &kernel; +}; + +namespace action { + +struct context { + explicit context(const dependencies &deps) noexcept : collaborators(deps) {} + + const dependencies collaborators; +}; + +} // namespace action + +} // namespace emel::speech::generator diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp new file mode 100644 index 00000000..d312c754 --- /dev/null +++ b/src/emel/speech/generator/errors.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "emel/error/error.hpp" + +namespace emel::speech::generator { + +enum class error : emel::error::type { + none = 0u, + uninitialized = (1u << 0), + already_initialized = (1u << 1), + invalid_request = (1u << 2), + cutover_pending = (1u << 3), + internal_error = (1u << 4), +}; + +} // namespace emel::speech::generator diff --git a/src/emel/speech/generator/events.hpp b/src/emel/speech/generator/events.hpp new file mode 100644 index 00000000..9dc51db6 --- /dev/null +++ b/src/emel/speech/generator/events.hpp @@ -0,0 +1,166 @@ +#pragma once + +#include +#include +#include + +#include "emel/callback.hpp" +#include "emel/error/error.hpp" + +namespace emel::speech::generator::events { + +struct initialize_done; +struct initialize_error; +struct generation_done; +struct generation_error; +struct stream_frame_done; +struct stream_frame_error; +struct flush_done; +struct flush_error; + +} // namespace emel::speech::generator::events + +namespace emel::speech::generator::event { + +struct initialize { + explicit initialize(emel::error::type &error_out_ref) noexcept + : error_out(error_out_ref) {} + + emel::error::type &error_out; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct generate { + generate(const std::string_view text_ref, std::span pcm_out_ref, + int32_t &sample_count_out_ref, + emel::error::type &error_out_ref) noexcept + : text(text_ref), pcm_out(pcm_out_ref), + sample_count_out(sample_count_out_ref), error_out(error_out_ref) {} + + std::string_view text = {}; + std::span reference_pcm = {}; + std::span pcm_out = {}; + int32_t &sample_count_out; + emel::error::type &error_out; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct stream_frame { + stream_frame(std::span pcm_in_ref, std::span pcm_out_ref, + int32_t &sample_count_out_ref, bool &produced_out_ref, + emel::error::type &error_out_ref) noexcept + : pcm_in(pcm_in_ref), pcm_out(pcm_out_ref), + sample_count_out(sample_count_out_ref), produced_out(produced_out_ref), + error_out(error_out_ref) {} + + std::span pcm_in = {}; + std::span pcm_out = {}; + int32_t &sample_count_out; + bool &produced_out; + emel::error::type &error_out; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct flush { + flush(std::span pcm_out_ref, int32_t &sample_count_out_ref, + bool &complete_out_ref, emel::error::type &error_out_ref) noexcept + : pcm_out(pcm_out_ref), sample_count_out(sample_count_out_ref), + complete_out(complete_out_ref), error_out(error_out_ref) {} + + std::span pcm_out = {}; + int32_t &sample_count_out; + bool &complete_out; + emel::error::type &error_out; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + +struct reset { + emel::error::type &error_out; +}; + +struct initialize_ctx { + emel::error::type err = {}; +}; + +struct generate_ctx { + emel::error::type err = {}; +}; + +struct stream_frame_ctx { + emel::error::type err = {}; +}; + +struct flush_ctx { + emel::error::type err = {}; +}; + +struct initialize_run { + const initialize &request; + initialize_ctx &ctx; +}; + +struct generate_run { + const generate &request; + generate_ctx &ctx; +}; + +struct stream_frame_run { + const stream_frame &request; + stream_frame_ctx &ctx; +}; + +struct flush_run { + const flush &request; + flush_ctx &ctx; +}; + +} // namespace emel::speech::generator::event + +namespace emel::speech::generator::events { + +struct initialize_done { + const event::initialize &request; +}; + +struct initialize_error { + const event::initialize &request; + emel::error::type err = {}; +}; + +struct generation_done { + const event::generate &request; + int32_t sample_count = 0; +}; + +struct generation_error { + const event::generate &request; + emel::error::type err = {}; +}; + +struct stream_frame_done { + const event::stream_frame &request; + int32_t sample_count = 0; + bool produced = false; +}; + +struct stream_frame_error { + const event::stream_frame &request; + emel::error::type err = {}; +}; + +struct flush_done { + const event::flush &request; + int32_t sample_count = 0; + bool complete = false; +}; + +struct flush_error { + const event::flush &request; + emel::error::type err = {}; +}; + +} // namespace emel::speech::generator::events diff --git a/src/emel/speech/generator/guards.hpp b/src/emel/speech/generator/guards.hpp new file mode 100644 index 00000000..ebe0511d --- /dev/null +++ b/src/emel/speech/generator/guards.hpp @@ -0,0 +1,80 @@ +#pragma once + +#include "emel/speech/generator/context.hpp" +#include "emel/speech/generator/events.hpp" + +namespace emel::speech::generator::guard { + +struct guard_generate_request_valid { + bool operator()(const event::generate_run &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.request.text.empty() && + !runtime_ev.request.pcm_out.empty(); + } +}; + +struct guard_generate_request_invalid { + bool operator()(const event::generate_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_generate_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_stream_request_valid { + bool operator()(const event::stream_frame_run &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.request.pcm_in.empty() && + !runtime_ev.request.pcm_out.empty(); + } +}; + +struct guard_stream_request_invalid { + bool operator()(const event::stream_frame_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_stream_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_flush_request_valid { + bool operator()(const event::flush_run &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.request.pcm_out.empty(); + } +}; + +struct guard_flush_request_invalid { + bool operator()(const event::flush_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_flush_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_initialize_done_callback_present { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return static_cast(runtime_ev.request.on_done); + } +}; + +struct guard_initialize_done_callback_absent { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_initialize_done_callback_present{}(runtime_ev, ctx); + } +}; + +template struct guard_error_callback_present { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return static_cast(runtime_ev.request.on_error); + } +}; + +template struct guard_error_callback_absent { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_error_callback_present{}(runtime_ev, ctx); + } +}; + +} // namespace emel::speech::generator::guard diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp new file mode 100644 index 00000000..7f1150aa --- /dev/null +++ b/src/emel/speech/generator/sm.hpp @@ -0,0 +1,346 @@ +#pragma once + +// benchmark: designed + +#include + +#include "emel/sm.hpp" +#include "emel/speech/generator/actions.hpp" +#include "emel/speech/generator/context.hpp" +#include "emel/speech/generator/events.hpp" +#include "emel/speech/generator/guards.hpp" + +namespace emel::speech::generator { + +struct state_uninitialized {}; +struct state_initialize_done_channel_decision {}; +struct state_initialize_error_ready_channel_decision {}; +struct state_ready {}; + +struct state_generate_conditioning {}; +struct state_generate_prefill {}; +struct state_generate_predict {}; +struct state_generate_sample {}; +struct state_generate_decode {}; +struct state_generate_postprocess {}; +struct state_generate_error_ready_channel_decision {}; +struct state_generate_error_uninitialized_channel_decision {}; +struct state_generate_error_errored_channel_decision {}; + +struct state_stream_encode {}; +struct state_stream_tokenize {}; +struct state_stream_prefill {}; +struct state_stream_predict {}; +struct state_stream_sample {}; +struct state_stream_detokenize {}; +struct state_stream_decode {}; +struct state_stream_postprocess {}; +struct state_stream_error_ready_channel_decision {}; +struct state_stream_error_uninitialized_channel_decision {}; +struct state_stream_error_errored_channel_decision {}; + +struct state_flush_decode {}; +struct state_flush_postprocess {}; +struct state_flush_error_ready_channel_decision {}; +struct state_flush_error_uninitialized_channel_decision {}; +struct state_flush_error_errored_channel_decision {}; +struct state_errored {}; + +/* +generic speech generator scaffold (single source of truth) + +state purpose +- state_ready accepts text-to-speech generation, duplex stream frames, and + decoder flush requests through separate event types so incompatible request + shapes are not representable as one flag-driven payload. +- generate states reserve the text/reference conditioning, prefill, + acoustic-representation prediction, sampling, decoding, and postprocessing + phases used by text/reference synthesis systems. +- stream states reserve the input encode, token alignment, prediction, + sampling, detokenization, streaming decode, and postprocessing phases used + by duplex streaming systems. + +control invariants +- the machine contains no model-family names, contracts, routes, constants, or + runtime handler tables. Model-family binding remains outside this component. +- planner, memory, graph, sampler, and kernel actors are injected by reference + and remain independently owned actors. +- every currently uncut phase is explicit in the transition graph. Valid + generation requests finish with cutover_pending rather than silently + succeeding or dispatching the maintained model-family implementation. +- request-local status remains in typed runtime events; context stores only + persistent injected collaborators. + +cutover contract +- each reserved phase will be replaced incrementally by synchronous child + dispatch while preserving this phase order and RTC boundary. +- decoder cadence, streaming versus synthesis input, callback presence, and + request validation remain guard-selected transitions. +*/ +struct model { + auto operator()() const { + namespace sml = stateforward::sml; + + using init_run = event::initialize_run; + using generate_run = event::generate_run; + using stream_run = event::stream_frame_run; + using flush_run = event::flush_run; + + using init_error_present = guard::guard_error_callback_present; + using init_error_absent = guard::guard_error_callback_absent; + using generate_error_present = + guard::guard_error_callback_present; + using generate_error_absent = + guard::guard_error_callback_absent; + using stream_error_present = + guard::guard_error_callback_present; + using stream_error_absent = guard::guard_error_callback_absent; + using flush_error_present = guard::guard_error_callback_present; + using flush_error_absent = guard::guard_error_callback_absent; + + // clang-format off + return sml::make_transition_table( + //------------------------------------------------------------------------------// + // Construction-time dependency injection makes initialization a pure + // lifecycle transition. Duplicate initialization remains observable. + sml::state <= + *sml::state + sml::event + / action::effect_accept_initialize{} + , sml::state <= + sml::state + sml::event + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::event + / action::effect_accept_initialize{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_initialize_done_callback_present{} ] + / action::effect_emit_initialize_done{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_initialize_done_callback_absent{} ] + , sml::state <= + sml::state + + sml::completion [ init_error_present{} ] + / action::effect_emit_initialize_error{} + , sml::state <= + sml::state + + sml::completion [ init_error_absent{} ] + + //------------------------------------------------------------------------------// + // Text/reference synthesis phase scaffold. + , sml::state <= sml::state + + sml::event [ guard::guard_generate_request_valid{} ] + / action::effect_prepare_generate{} + , sml::state <= + sml::state + sml::event + [ guard::guard_generate_request_invalid{} ] + / action::effect_fail_generate{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= + sml::state + sml::completion + / action::effect_fail_generate{} + , sml::state <= + sml::state + + sml::completion [ generate_error_present{} ] + / action::effect_emit_generation_error{} + , sml::state <= + sml::state + + sml::completion [ generate_error_absent{} ] + + //------------------------------------------------------------------------------// + // Duplex streaming phase scaffold. + , sml::state <= sml::state + + sml::event [ guard::guard_stream_request_valid{} ] + / action::effect_prepare_stream_frame{} + , sml::state <= + sml::state + sml::event + [ guard::guard_stream_request_invalid{} ] + / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion + , sml::state <= + sml::state + sml::completion + / action::effect_fail_stream_frame{} + , sml::state <= + sml::state + + sml::completion [ stream_error_present{} ] + / action::effect_emit_stream_frame_error{} + , sml::state <= + sml::state + + sml::completion [ stream_error_absent{} ] + + //------------------------------------------------------------------------------// + // Buffered or streaming decoder flush scaffold. + , sml::state <= sml::state + + sml::event [ guard::guard_flush_request_valid{} ] + / action::effect_prepare_flush{} + , sml::state <= + sml::state + sml::event + [ guard::guard_flush_request_invalid{} ] + / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion + , sml::state <= + sml::state + sml::completion + / action::effect_fail_flush{} + , sml::state <= + sml::state + + sml::completion [ flush_error_present{} ] + / action::effect_emit_flush_error{} + , sml::state <= + sml::state + + sml::completion [ flush_error_absent{} ] + + //------------------------------------------------------------------------------// + // Known requests before initialization and after unexpected events. + , sml::state <= + sml::state + sml::event + / action::effect_fail_generate{} + , sml::state <= + sml::state + + sml::completion [ generate_error_present{} ] + / action::effect_emit_generation_error{} + , sml::state <= + sml::state + + sml::completion [ generate_error_absent{} ] + , sml::state <= + sml::state + sml::event + / action::effect_fail_stream_frame{} + , sml::state <= + sml::state + + sml::completion [ stream_error_present{} ] + / action::effect_emit_stream_frame_error{} + , sml::state <= + sml::state + + sml::completion [ stream_error_absent{} ] + , sml::state <= + sml::state + sml::event + / action::effect_fail_flush{} + , sml::state <= + sml::state + + sml::completion [ flush_error_present{} ] + / action::effect_emit_flush_error{} + , sml::state <= + sml::state + + sml::completion [ flush_error_absent{} ] + , sml::state <= sml::state + + sml::event + / action::effect_reject{} + + , sml::state <= + sml::state + sml::event + / action::effect_fail_generate{} + , sml::state <= + sml::state + + sml::completion [ generate_error_present{} ] + / action::effect_emit_generation_error{} + , sml::state <= + sml::state + + sml::completion [ generate_error_absent{} ] + , sml::state <= + sml::state + sml::event + / action::effect_fail_stream_frame{} + , sml::state <= + sml::state + + sml::completion [ stream_error_present{} ] + / action::effect_emit_stream_frame_error{} + , sml::state <= + sml::state + + sml::completion [ stream_error_absent{} ] + , sml::state <= + sml::state + sml::event + / action::effect_fail_flush{} + , sml::state <= + sml::state + + sml::completion [ flush_error_present{} ] + / action::effect_emit_flush_error{} + , sml::state <= + sml::state + + sml::completion [ flush_error_absent{} ] + + //------------------------------------------------------------------------------// + // Reset preserves injected collaborators and returns to ready. + , sml::state <= sml::state + + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} + + //------------------------------------------------------------------------------// + // Unknown external events are observable through state_errored. + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + ); + // clang-format on + } +}; + +struct sm : public emel::sm { + using base_type = emel::sm; + using base_type::is; + using base_type::process_event; + using base_type::visit_current_states; + + explicit sm(const dependencies &deps) : base_type(std::in_place, deps) {} + + bool process_event(const event::initialize &ev) { + event::initialize_ctx ctx{}; + const bool accepted = + base_type::process_event(event::initialize_run{ev, ctx}); + return accepted && ctx.err == action::error_code(error::none); + } + + bool process_event(const event::generate &ev) { + event::generate_ctx ctx{}; + const bool accepted = + base_type::process_event(event::generate_run{ev, ctx}); + return accepted && ctx.err == action::error_code(error::none); + } + + bool process_event(const event::stream_frame &ev) { + event::stream_frame_ctx ctx{}; + const bool accepted = + base_type::process_event(event::stream_frame_run{ev, ctx}); + return accepted && ctx.err == action::error_code(error::none); + } + + bool process_event(const event::flush &ev) { + event::flush_ctx ctx{}; + const bool accepted = base_type::process_event(event::flush_run{ev, ctx}); + return accepted && ctx.err == action::error_code(error::none); + } + + bool process_event(const event::reset &ev) { + const bool accepted = base_type::process_event(ev); + return accepted && ev.error_out == action::error_code(error::none); + } +}; + +using Generator = sm; + +} // namespace emel::speech::generator diff --git a/src/emel/text/encoders/sm.hpp b/src/emel/text/encoders/sm.hpp deleted file mode 100644 index fc9e3f6f..00000000 --- a/src/emel/text/encoders/sm.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -/* -design doc: docs/designs/text/encoders/encoder.design.md - --- - title: text/encoders architecture design - status: rolling - --- - - # text/encoders architecture design - - this document defines the text-domain encoder actor cluster that maps - preprocessed text fragments to token ids. this is distinct from model - encoders (vision/audio/etc) and lives under the text domain for clarity. - - ## role - - text/encoders is the algorithmic encoder cluster used by the tokenizer codec. - - it encodes raw text fragments (or preprocessed fragments) into token ids. - - it is model/vocab-aware but does not perform special-token parsing. - - ## scope - - text-domain tokenization only (BPE/SPM/WPM/UGM/RWKV/PLAMO2/fallback). - - excludes model encoders used for multimodal inputs. - - ## public interface (current contract) - - `event::encode`: - - inputs: `vocab`, `text`, `preprocessed`, `token_ids`, - `token_count_out`, `error_out`, optional sync callbacks. - - outputs: `token_count_out` and `error_out`. - - callbacks (`dispatch_done`/`dispatch_error`) are invoked synchronously and are - not stored. - - ## composition - - per-algorithm SMs: - - `bpe`, `spm`, `wpm`, `ugm`, `rwkv`, `plamo2`, `fallback`. - - each encoder SM uses the same single-step encode flow: - `initialized` -> `encoding` -> `encode_decision` -> (`done` | `errored`), - with explicit unexpected-event handling. - - `text/encoders::any` (sm_any) selects the active encoder kind and dispatches - `event::encode`. - - ## invariants - - no allocations during dispatch. - - no special-token parsing; caller handles special-token policy. - - bounded work per encode request. - - ## error mapping - - invalid requests or capacity errors -> - `emel::text::encoders::error::to_emel(emel::text::encoders::error::code::invalid_argument)`. - - kernel/data errors propagate via `error_out`. - - ## status - - implemented under `src/emel/text/encoders/...` with namespace - `emel::text::encoders`. - - ## open questions - - should `text/encoder` expose a unified `sm` alias or require `any` - everywhere? - - how should byte-fallback support be represented (encoder vs tokenizer - helper)? -*/ - -// benchmark: designed - -#include "emel/text/encoders/bpe/sm.hpp" -#include "emel/text/encoders/fallback/sm.hpp" -#include "emel/text/encoders/plamo2/sm.hpp" -#include "emel/text/encoders/rwkv/sm.hpp" -#include "emel/text/encoders/spm/sm.hpp" -#include "emel/text/encoders/ugm/sm.hpp" -#include "emel/text/encoders/wpm/sm.hpp" - -namespace emel::text::encoders { - -using sm = emel::text::encoders::bpe::sm; -using Encoder = sm; - -} // namespace emel::text::encoders diff --git a/tests/diarization/sortformer/request/lifecycle_tests.cpp b/tests/diarization/sortformer/request/lifecycle_tests.cpp index 956c818a..8ed9de85 100644 --- a/tests/diarization/sortformer/request/lifecycle_tests.cpp +++ b/tests/diarization/sortformer/request/lifecycle_tests.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -161,10 +160,6 @@ diarization_request::event::prepare make_request( } // namespace -TEST_CASE("sortformer request keeps top-level compatibility alias") { - CHECK((std::is_same_v)); -} - TEST_CASE("diarization request extracts deterministic Sortformer features") { auto model = std::make_unique(); const auto contract = make_contract(model->model); diff --git a/tests/io/loader/lifecycle_tests.cpp b/tests/io/loader/lifecycle_tests.cpp index 168aba77..89a82d92 100644 --- a/tests/io/loader/lifecycle_tests.cpp +++ b/tests/io/loader/lifecycle_tests.cpp @@ -139,11 +139,9 @@ uint32_t occurrence_count(const std::string_view source, TEST_CASE("io loader exposes canonical machine aliases") { emel::io::loader::sm loader{}; - emel::io::sm io_loader{}; emel::IoLoader top_level_loader{}; CHECK(loader.is(stateforward::sml::state)); - CHECK(io_loader.is(stateforward::sml::state)); CHECK(top_level_loader.is( stateforward::sml::state)); } diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp new file mode 100644 index 00000000..47c29d8e --- /dev/null +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -0,0 +1,260 @@ +#include "doctest/doctest.h" + +#include +#include +#include +#include +#include + +#include "../../allocation_tracker.hpp" +#include "emel/error/error.hpp" +#include "emel/speech/generator/sm.hpp" + +namespace { + +namespace generator = emel::speech::generator; +namespace sml = stateforward::sml; + +struct callback_capture { + int32_t initialize_done_calls = 0; + int32_t initialize_error_calls = 0; + int32_t generation_error_calls = 0; + int32_t stream_error_calls = 0; + int32_t flush_error_calls = 0; + emel::error::type err = generator::action::error_code(generator::error::none); +}; + +void record_initialize_done( + callback_capture &capture, + const generator::events::initialize_done &) noexcept { + ++capture.initialize_done_calls; +} + +void record_initialize_error( + callback_capture &capture, + const generator::events::initialize_error &ev) noexcept { + ++capture.initialize_error_calls; + capture.err = ev.err; +} + +void record_generation_error( + callback_capture &capture, + const generator::events::generation_error &ev) noexcept { + ++capture.generation_error_calls; + capture.err = ev.err; +} + +void record_stream_error( + callback_capture &capture, + const generator::events::stream_frame_error &ev) noexcept { + ++capture.stream_error_calls; + capture.err = ev.err; +} + +void record_flush_error(callback_capture &capture, + const generator::events::flush_error &ev) noexcept { + ++capture.flush_error_calls; + capture.err = ev.err; +} + +struct fixture { + emel::batch::planner::sm planner{}; + emel::memory::hybrid::sm memory{}; + emel::graph::sm graph{}; + emel::logits::sampler::sm sampler{}; + emel::kernel::sm kernel{}; + generator::dependencies dependencies{planner, memory, graph, sampler, kernel}; + generator::sm machine{dependencies}; + + bool initialize(callback_capture *capture = nullptr) { + emel::error::type err = + generator::action::error_code(generator::error::none); + generator::event::initialize ev{err}; + if (capture != nullptr) { + ev.on_done = + emel::callback:: + from(capture); + } + return machine.process_event(ev); + } +}; + +static_assert(std::is_reference_v); +static_assert(std::is_reference_v); +static_assert(std::is_reference_v); +static_assert(std::is_reference_v); +static_assert(std::is_reference_v); + +} // namespace + +TEST_CASE("speech_generator_initializes_with_injected_collaborators") { + auto test = std::make_unique(); + callback_capture capture{}; + + REQUIRE(test->initialize(&capture)); + CHECK(capture.initialize_done_calls == 1); + CHECK(test->machine.is(sml::state)); + + emel::error::type err = generator::action::error_code(generator::error::none); + generator::event::initialize duplicate{err}; + duplicate.on_error = + emel::callback::from< + callback_capture, record_initialize_error>(&capture); + + CHECK_FALSE(test->machine.process_event(duplicate)); + CHECK(err == + generator::action::error_code(generator::error::already_initialized)); + CHECK(capture.initialize_error_calls == 1); + CHECK(capture.err == err); + CHECK(test->machine.is(sml::state)); +} + +TEST_CASE("speech_generator_exposes_synthesis_phases_without_hidden_cutover") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + + std::array reference_pcm{}; + std::array pcm_out{}; + int32_t sample_count = 99; + emel::error::type err = generator::action::error_code(generator::error::none); + callback_capture capture{}; + generator::event::generate generate_ev{"Hello from the generic generator.", + std::span{pcm_out}, + sample_count, err}; + generate_ev.reference_pcm = std::span{reference_pcm}; + generate_ev.on_error = + emel::callback::from< + callback_capture, record_generation_error>(&capture); + + CHECK_FALSE(test->machine.process_event(generate_ev)); + CHECK(err == + generator::action::error_code(generator::error::cutover_pending)); + CHECK(sample_count == 0); + CHECK(capture.generation_error_calls == 1); + CHECK(capture.err == err); + CHECK(test->machine.is(sml::state)); +} + +TEST_CASE("speech_generator_exposes_duplex_and_flush_phases") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + + std::array pcm_in{}; + std::array pcm_out{}; + int32_t sample_count = 99; + bool produced = true; + emel::error::type err = generator::action::error_code(generator::error::none); + callback_capture capture{}; + generator::event::stream_frame stream_ev{std::span{pcm_in}, + std::span{pcm_out}, + sample_count, produced, err}; + stream_ev.on_error = + emel::callback::from< + callback_capture, record_stream_error>(&capture); + + CHECK_FALSE(test->machine.process_event(stream_ev)); + CHECK(err == + generator::action::error_code(generator::error::cutover_pending)); + CHECK(sample_count == 0); + CHECK_FALSE(produced); + CHECK(capture.stream_error_calls == 1); + CHECK(test->machine.is(sml::state)); + + sample_count = 99; + bool complete = true; + generator::event::flush flush_ev{std::span{pcm_out}, sample_count, + complete, err}; + flush_ev.on_error = + emel::callback::from< + callback_capture, record_flush_error>(&capture); + + CHECK_FALSE(test->machine.process_event(flush_ev)); + CHECK(err == + generator::action::error_code(generator::error::cutover_pending)); + CHECK(sample_count == 0); + CHECK_FALSE(complete); + CHECK(capture.flush_error_calls == 1); + CHECK(test->machine.is(sml::state)); +} + +TEST_CASE("speech_generator_rejects_uninitialized_and_invalid_requests") { + auto test = std::make_unique(); + std::array pcm{}; + int32_t sample_count = 99; + emel::error::type err = generator::action::error_code(generator::error::none); + generator::event::generate before_initialize{"speech", std::span{pcm}, + sample_count, err}; + + CHECK_FALSE(test->machine.process_event(before_initialize)); + CHECK(err == generator::action::error_code(generator::error::uninitialized)); + CHECK(test->machine.is(sml::state)); + + generator::event::reset reset_before_initialize{err}; + CHECK_FALSE(test->machine.process_event(reset_before_initialize)); + CHECK(err == generator::action::error_code(generator::error::uninitialized)); + CHECK(test->machine.is(sml::state)); + + REQUIRE(test->initialize()); + generator::event::generate invalid_generate{"", std::span{pcm}, + sample_count, err}; + CHECK_FALSE(test->machine.process_event(invalid_generate)); + CHECK(err == + generator::action::error_code(generator::error::invalid_request)); + + bool produced = true; + generator::event::stream_frame invalid_stream{std::span{}, + std::span{pcm}, + sample_count, produced, err}; + CHECK_FALSE(test->machine.process_event(invalid_stream)); + CHECK(err == + generator::action::error_code(generator::error::invalid_request)); + + bool complete = true; + generator::event::flush invalid_flush{std::span{}, sample_count, + complete, err}; + CHECK_FALSE(test->machine.process_event(invalid_flush)); + CHECK(err == + generator::action::error_code(generator::error::invalid_request)); + CHECK(test->machine.is(sml::state)); +} + +TEST_CASE("speech_generator_reset_recovers_from_unexpected_event") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + + struct unknown_event {}; + test->machine.process_event(unknown_event{}); + CHECK(test->machine.is(sml::state)); + + emel::error::type err = generator::action::error_code(generator::error::none); + generator::event::reset reset_ev{err}; + CHECK(test->machine.process_event(reset_ev)); + CHECK(err == generator::action::error_code(generator::error::none)); + CHECK(test->machine.is(sml::state)); +} + +TEST_CASE("speech_generator_scaffold_dispatch_is_allocation_free") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + + std::array pcm_out{}; + int32_t sample_count = 0; + emel::error::type err = generator::action::error_code(generator::error::none); + generator::event::generate generate_ev{ + "allocation probe", std::span{pcm_out}, sample_count, err}; + bool all_rejected_as_pending = true; + size_t allocation_count = 0u; + { + emel::test::allocation::allocation_scope allocations; + for (int32_t dispatch = 0; dispatch < 32; ++dispatch) { + all_rejected_as_pending = !test->machine.process_event(generate_ev) && + err == generator::action::error_code( + generator::error::cutover_pending) && + all_rejected_as_pending; + } + allocation_count = allocations.allocations(); + } + + CHECK(all_rejected_as_pending); + CHECK(allocation_count == 0u); +} diff --git a/tests/text/generator/legacy_compatibility_tests.cpp b/tests/text/generator/legacy_compatibility_tests.cpp deleted file mode 100644 index c4deeb26..00000000 --- a/tests/text/generator/legacy_compatibility_tests.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -#include "emel/generator/actions.hpp" -#include "emel/generator/context.hpp" -#include "emel/generator/detail.hpp" -#include "emel/generator/errors.hpp" -#include "emel/generator/events.hpp" -#include "emel/generator/guards.hpp" -#include "emel/generator/initializer/actions.hpp" -#include "emel/generator/initializer/context.hpp" -#include "emel/generator/initializer/detail.hpp" -#include "emel/generator/initializer/guards.hpp" -#include "emel/generator/initializer/sm.hpp" -#include "emel/generator/prefill/actions.hpp" -#include "emel/generator/prefill/context.hpp" -#include "emel/generator/prefill/detail.hpp" -#include "emel/generator/prefill/guards.hpp" -#include "emel/generator/prefill/sm.hpp" -#include "emel/generator/sm.hpp" -#include "emel/text/generator/sm.hpp" - -namespace { - -static_assert(std::is_same_v); -static_assert(std::is_same_v); -static_assert(std::is_same_v); -static_assert(std::is_same_v); -static_assert(std::is_same_v); -static_assert(std::is_same_v); - -} // namespace - -TEST_CASE("legacy generator headers forward to text generator surface") { - CHECK((std::is_same_v)); -} From d1002f966d36dcd8c4a801c958c04aef4004fd97 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 17:32:13 -0500 Subject: [PATCH 11/61] refactor: route personaplex through generic speech generator --- src/emel/machines.hpp | 3 +- src/emel/speech/generator/actions.hpp | 414 +++++++-- src/emel/speech/generator/any.hpp | 3 +- src/emel/speech/generator/context.hpp | 53 +- src/emel/speech/generator/errors.hpp | 9 + src/emel/speech/generator/events.hpp | 84 +- src/emel/speech/generator/guards.hpp | 235 ++++- src/emel/speech/generator/sm.hpp | 587 ++++++++----- tests/speech/generator/lifecycle_tests.cpp | 800 ++++++++++++++---- tools/bench/personaplex_compare_tests.cpp | 18 +- .../bench/speech/personaplex_emel_runner.cpp | 248 ++++-- 11 files changed, 1823 insertions(+), 631 deletions(-) diff --git a/src/emel/machines.hpp b/src/emel/machines.hpp index ebba237f..9ce5cd3c 100644 --- a/src/emel/machines.hpp +++ b/src/emel/machines.hpp @@ -37,7 +37,8 @@ using SortformerPipeline = emel::diarization::sortformer::pipeline::sm; using OmniEmbedEmbeddingsGenerator = emel::embeddings::generator::omniembed::sm; using EmbeddingsGenerator = emel::embeddings::generator::sm; using MimiCodec = emel::speech::codec::mimi::sm; -using SpeechGenerator = emel::speech::generator::sm; +template +using SpeechGenerator = emel::speech::generator::sm; using EncoderAny = emel::text::encoders::any; using EncoderBpe = emel::text::encoders::bpe::sm; using EncoderSpm = emel::text::encoders::spm::sm; diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index dfe0f985..4d25ee2d 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -1,6 +1,11 @@ #pragma once +#include +#include + #include "emel/error/error.hpp" +#include "emel/memory/streaming/errors.hpp" +#include "emel/memory/streaming/events.hpp" #include "emel/speech/generator/context.hpp" #include "emel/speech/generator/errors.hpp" #include "emel/speech/generator/events.hpp" @@ -11,43 +16,331 @@ inline emel::error::type error_code(const error value) noexcept { return emel::error::cast(value); } -struct effect_accept_initialize { +template +void effect_store_error(const runtime_event_type &runtime_ev, + const error value) noexcept { + runtime_ev.ctx.err = error_code(value); + runtime_ev.request.error_out = runtime_ev.ctx.err; +} + +template struct effect_initialize_temporal_positions { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + int32_t child_err = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.child_accepted = + ctx.collaborators.temporal_positions.process_event( + emel::memory::streaming::event::initialize{child_err}); + runtime_ev.ctx.child_err = static_cast(child_err); + } +}; + +template +struct effect_initialize_secondary_positions { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + int32_t child_err = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.child_accepted = + ctx.collaborators.secondary_positions.process_event( + emel::memory::streaming::event::initialize{child_err}); + runtime_ev.ctx.child_err = static_cast(child_err); + } +}; + +template struct effect_initialize_encoder { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + auto request = ctx.collaborators.encoder_initialize; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.encoder.process_event(request); + } +}; + +template struct effect_initialize_decoder { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + auto request = ctx.collaborators.decoder_initialize; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.decoder.process_event(request); + } +}; + +template struct effect_initialize_runtime { void operator()(const event::initialize_run &runtime_ev, - const context &) const noexcept { + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + auto request = ctx.collaborators.runtime_initialize; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.runtime.process_event(request); + } +}; + +template struct effect_initialize_predictor { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + auto request = ctx.collaborators.predictor_initialize; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template struct effect_initialize_conditioning { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + auto request = ctx.collaborators.conditioning_initialize; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template struct effect_publish_initialize_done { + void operator()(const event::initialize_run &runtime_ev, + const context &) const noexcept { runtime_ev.ctx.err = error_code(error::none); runtime_ev.request.error_out = runtime_ev.ctx.err; } }; -template struct effect_fail_initialize { +template +struct effect_fail_initialize { void operator()(const event::initialize_run &runtime_ev, - const context &) const noexcept { - runtime_ev.ctx.err = error_code(error_value); + const context &) const noexcept { + effect_store_error(runtime_ev, error_value); + } +}; + +template struct effect_emit_initialize_done { + void operator()(const event::initialize_run &runtime_ev, + const context &ctx) const noexcept { + runtime_ev.request.on_done(events::initialize_done{ + runtime_ev.request, ctx.collaborators.frame_samples, + ctx.collaborators.codebook_count}); + } +}; + +template struct effect_emit_initialize_error { + void operator()(const event::initialize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::initialize_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +template struct effect_condition_voice { + void operator()(const event::condition_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.graph_err = 0; + runtime_ev.ctx.complete = false; + runtime_ev.ctx.remaining = -1; + typename dependencies_type::voice_condition_event request{}; + request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; + request.complete_out = &runtime_ev.ctx.complete; + request.remaining_frames_out = &runtime_ev.ctx.remaining; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template struct effect_begin_prompt_conditioning { + void operator()(const event::condition_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + typename dependencies_type::prompt_begin_event request{}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template struct effect_condition_prompt { + void operator()(const event::condition_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.graph_err = 0; + runtime_ev.ctx.complete = false; + runtime_ev.ctx.remaining = -1; + typename dependencies_type::prompt_condition_event request{}; + request.text_token = runtime_ev.request.token; + request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; + request.complete_out = &runtime_ev.ctx.complete; + request.remaining_frames_out = &runtime_ev.ctx.remaining; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template struct effect_publish_condition_pending { + void operator()(const event::condition_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.complete_out = false; + runtime_ev.request.remaining_out = runtime_ev.ctx.remaining; + runtime_ev.ctx.err = error_code(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_publish_condition_complete { + void operator()(const event::condition_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.complete_out = true; + runtime_ev.request.remaining_out = 0; + runtime_ev.ctx.err = error_code(error::none); runtime_ev.request.error_out = runtime_ev.ctx.err; } }; -struct effect_prepare_generate { +template +struct effect_fail_condition { + void operator()(const event::condition_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.complete_out = false; + runtime_ev.request.remaining_out = -1; + effect_store_error(runtime_ev, error_value); + } +}; + +template struct effect_emit_condition_done { + void operator()(const event::condition_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_done(events::condition_done{ + runtime_ev.request, runtime_ev.request.complete_out, + runtime_ev.request.remaining_out}); + } +}; + +template struct effect_emit_condition_error { + void operator()(const event::condition_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::condition_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +template struct effect_prepare_generate { void operator()(const event::generate_run &runtime_ev, - const context &) const noexcept { + const context &) const noexcept { runtime_ev.request.sample_count_out = 0; runtime_ev.ctx.err = error_code(error::none); runtime_ev.request.error_out = runtime_ev.ctx.err; } }; -template struct effect_fail_generate { +template +struct effect_fail_generate { void operator()(const event::generate_run &runtime_ev, - const context &) const noexcept { + const context &) const noexcept { runtime_ev.request.sample_count_out = 0; - runtime_ev.ctx.err = error_code(error_value); + effect_store_error(runtime_ev, error_value); + } +}; + +template struct effect_emit_generation_error { + void operator()(const event::generate_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::generation_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +template struct effect_encode_stream_frame { + void operator()(const event::stream_frame_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + typename dependencies_type::encode_event request{ + runtime_ev.request.pcm_in, ctx.collaborators.input_codes}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.encoder.process_event(request); + } +}; + +template struct effect_encode_flush_frame { + void operator()(const event::flush_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + typename dependencies_type::encode_event request{ + std::span{ctx.collaborators.silence_pcm}, + ctx.collaborators.input_codes}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.encoder.process_event(request); + } +}; + +template +struct effect_predict_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.graph_err = 0; + runtime_ev.ctx.produced = false; + std::fill(ctx.collaborators.output_codes.begin(), + ctx.collaborators.output_codes.end(), -1); + typename dependencies_type::predict_event request{ + std::span{ctx.collaborators.input_codes}, + ctx.collaborators.output_codes, runtime_ev.ctx.text_token}; + request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; + request.produced_out = &runtime_ev.ctx.produced; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template +struct effect_decode_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + typename dependencies_type::decode_event request{ + std::span{ctx.collaborators.output_codes}, + runtime_ev.request.pcm_out}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.decoder.process_event(request); + } +}; + +template +void effect_publish_frame_tokens(const runtime_event_type &runtime_ev, + const auto &ctx) noexcept { + std::copy(ctx.collaborators.input_codes.begin(), + ctx.collaborators.input_codes.end(), + runtime_ev.request.encoded_tokens_out.begin()); + std::copy(ctx.collaborators.output_codes.begin(), + ctx.collaborators.output_codes.end(), + runtime_ev.request.generated_tokens_out.begin()); + runtime_ev.request.text_token_out = runtime_ev.ctx.text_token; +} + +template struct effect_publish_stream_frame_produced { + void operator()(const event::stream_frame_run &runtime_ev, + const context &ctx) const noexcept { + effect_publish_frame_tokens(runtime_ev, ctx); + runtime_ev.request.sample_count_out = ctx.collaborators.frame_samples; + runtime_ev.request.produced_out = true; + runtime_ev.ctx.err = error_code(error::none); runtime_ev.request.error_out = runtime_ev.ctx.err; } }; -struct effect_prepare_stream_frame { +template struct effect_publish_stream_frame_pending { void operator()(const event::stream_frame_run &runtime_ev, - const context &) const noexcept { + const context &ctx) const noexcept { + effect_publish_frame_tokens(runtime_ev, ctx); runtime_ev.request.sample_count_out = 0; runtime_ev.request.produced_out = false; runtime_ev.ctx.err = error_code(error::none); @@ -55,90 +348,93 @@ struct effect_prepare_stream_frame { } }; -template struct effect_fail_stream_frame { +template +struct effect_fail_stream_frame { void operator()(const event::stream_frame_run &runtime_ev, - const context &) const noexcept { + const context &) const noexcept { runtime_ev.request.sample_count_out = 0; runtime_ev.request.produced_out = false; - runtime_ev.ctx.err = error_code(error_value); - runtime_ev.request.error_out = runtime_ev.ctx.err; + effect_store_error(runtime_ev, error_value); } }; -struct effect_prepare_flush { +template struct effect_emit_stream_frame_done { + void operator()(const event::stream_frame_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_done(events::stream_frame_done{ + runtime_ev.request, runtime_ev.request.sample_count_out, + runtime_ev.request.produced_out}); + } +}; + +template struct effect_emit_stream_frame_error { + void operator()(const event::stream_frame_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_error( + events::stream_frame_error{runtime_ev.request, runtime_ev.ctx.err}); + } +}; + +template struct effect_publish_flush_produced { void operator()(const event::flush_run &runtime_ev, - const context &) const noexcept { - runtime_ev.request.sample_count_out = 0; + const context &ctx) const noexcept { + effect_publish_frame_tokens(runtime_ev, ctx); + runtime_ev.request.sample_count_out = ctx.collaborators.frame_samples; runtime_ev.request.complete_out = false; runtime_ev.ctx.err = error_code(error::none); runtime_ev.request.error_out = runtime_ev.ctx.err; } }; -template struct effect_fail_flush { +template struct effect_publish_flush_pending { void operator()(const event::flush_run &runtime_ev, - const context &) const noexcept { + const context &ctx) const noexcept { + effect_publish_frame_tokens(runtime_ev, ctx); runtime_ev.request.sample_count_out = 0; runtime_ev.request.complete_out = false; - runtime_ev.ctx.err = error_code(error_value); + runtime_ev.ctx.err = error_code(error::none); runtime_ev.request.error_out = runtime_ev.ctx.err; } }; -struct effect_emit_initialize_done { - void operator()(const event::initialize_run &runtime_ev, - const context &) const noexcept { - runtime_ev.request.on_done(events::initialize_done{runtime_ev.request}); - } -}; - -struct effect_emit_initialize_error { - void operator()(const event::initialize_run &runtime_ev, - const context &) const noexcept { - runtime_ev.request.on_error( - events::initialize_error{runtime_ev.request, runtime_ev.ctx.err}); - } -}; - -struct effect_emit_generation_error { - void operator()(const event::generate_run &runtime_ev, - const context &) const noexcept { - runtime_ev.request.on_error( - events::generation_error{runtime_ev.request, runtime_ev.ctx.err}); +template struct effect_fail_flush { + void operator()(const event::flush_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = 0; + runtime_ev.request.complete_out = false; + effect_store_error(runtime_ev, error_value); } }; -struct effect_emit_stream_frame_error { - void operator()(const event::stream_frame_run &runtime_ev, - const context &) const noexcept { - runtime_ev.request.on_error( - events::stream_frame_error{runtime_ev.request, runtime_ev.ctx.err}); +template struct effect_emit_flush_done { + void operator()(const event::flush_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_done(events::flush_done{ + runtime_ev.request, runtime_ev.request.sample_count_out, + runtime_ev.request.complete_out}); } }; -struct effect_emit_flush_error { +template struct effect_emit_flush_error { void operator()(const event::flush_run &runtime_ev, - const context &) const noexcept { + const context &) const noexcept { runtime_ev.request.on_error( events::flush_error{runtime_ev.request, runtime_ev.ctx.err}); } }; -struct effect_reset { - void operator()(const event::reset &ev, const context &) const noexcept { - ev.error_out = error_code(error::none); - } -}; - -template struct effect_reject { - void operator()(const event::reset &ev, const context &) const noexcept { +template +struct effect_reject_reset { + void operator()(const event::reset &ev, + const context &) const noexcept { ev.error_out = error_code(error_value); } }; -struct effect_unexpected { +template struct effect_unexpected { template - void operator()(const event_type &, const context &) const noexcept {} + void operator()(const event_type &, + const context &) const noexcept {} }; } // namespace emel::speech::generator::action diff --git a/src/emel/speech/generator/any.hpp b/src/emel/speech/generator/any.hpp index e3402025..55eed06f 100644 --- a/src/emel/speech/generator/any.hpp +++ b/src/emel/speech/generator/any.hpp @@ -4,6 +4,7 @@ namespace emel::speech::generator { -using SpeechGenerator = sm; +template +using SpeechGenerator = sm; } // namespace emel::speech::generator diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index 8f2e45aa..338f1212 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -1,29 +1,38 @@ #pragma once -#include "emel/batch/planner/sm.hpp" -#include "emel/graph/sm.hpp" -#include "emel/kernel/sm.hpp" -#include "emel/logits/sampler/sm.hpp" -#include "emel/memory/hybrid/sm.hpp" - -namespace emel::speech::generator { - -struct dependencies { - emel::batch::planner::sm &planner; - emel::memory::hybrid::sm &memory; - emel::graph::sm &graph; - emel::logits::sampler::sm &sampler; - emel::kernel::sm &kernel; +namespace emel::speech::generator::action { + +template +concept generator_dependencies = requires(dependencies_type deps) { + typename dependencies_type::voice_condition_event; + typename dependencies_type::prompt_begin_event; + typename dependencies_type::prompt_condition_event; + typename dependencies_type::encode_event; + typename dependencies_type::predict_event; + typename dependencies_type::decode_event; + deps.temporal_positions; + deps.secondary_positions; + deps.encoder; + deps.decoder; + deps.runtime; + deps.predictor; + deps.encoder_initialize; + deps.decoder_initialize; + deps.runtime_initialize; + deps.predictor_initialize; + deps.conditioning_initialize; + deps.silence_pcm; + deps.input_codes; + deps.output_codes; + deps.frame_samples; + deps.codebook_count; }; -namespace action { +template struct context { + explicit context(const dependencies_type &deps) noexcept + : collaborators(deps) {} -struct context { - explicit context(const dependencies &deps) noexcept : collaborators(deps) {} - - const dependencies collaborators; + const dependencies_type collaborators; }; -} // namespace action - -} // namespace emel::speech::generator +} // namespace emel::speech::generator::action diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp index d312c754..a462924d 100644 --- a/src/emel/speech/generator/errors.hpp +++ b/src/emel/speech/generator/errors.hpp @@ -11,6 +11,15 @@ enum class error : emel::error::type { invalid_request = (1u << 2), cutover_pending = (1u << 3), internal_error = (1u << 4), + memory_initialize_failed = (1u << 5), + encoder_initialize_failed = (1u << 6), + decoder_initialize_failed = (1u << 7), + runtime_initialize_failed = (1u << 8), + predictor_initialize_failed = (1u << 9), + conditioning_failed = (1u << 10), + encode_failed = (1u << 11), + predict_failed = (1u << 12), + decode_failed = (1u << 13), }; } // namespace emel::speech::generator diff --git a/src/emel/speech/generator/events.hpp b/src/emel/speech/generator/events.hpp index 9dc51db6..eab50fed 100644 --- a/src/emel/speech/generator/events.hpp +++ b/src/emel/speech/generator/events.hpp @@ -11,6 +11,8 @@ namespace emel::speech::generator::events { struct initialize_done; struct initialize_error; +struct condition_done; +struct condition_error; struct generation_done; struct generation_error; struct stream_frame_done; @@ -31,6 +33,23 @@ struct initialize { emel::callback on_error = {}; }; +struct condition { + condition(const int32_t token_ref, bool &complete_out_ref, + int32_t &remaining_out_ref, + emel::error::type &error_out_ref) noexcept + : token(token_ref), complete_out(complete_out_ref), + remaining_out(remaining_out_ref), error_out(error_out_ref) {} + + int32_t token = -1; + std::string_view text = {}; + std::span reference_pcm = {}; + bool &complete_out; + int32_t &remaining_out; + emel::error::type &error_out; + emel::callback on_done = {}; + emel::callback on_error = {}; +}; + struct generate { generate(const std::string_view text_ref, std::span pcm_out_ref, int32_t &sample_count_out_ref, @@ -49,14 +68,23 @@ struct generate { struct stream_frame { stream_frame(std::span pcm_in_ref, std::span pcm_out_ref, - int32_t &sample_count_out_ref, bool &produced_out_ref, + std::span encoded_tokens_out_ref, + std::span generated_tokens_out_ref, + int32_t &text_token_out_ref, int32_t &sample_count_out_ref, + bool &produced_out_ref, emel::error::type &error_out_ref) noexcept : pcm_in(pcm_in_ref), pcm_out(pcm_out_ref), + encoded_tokens_out(encoded_tokens_out_ref), + generated_tokens_out(generated_tokens_out_ref), + text_token_out(text_token_out_ref), sample_count_out(sample_count_out_ref), produced_out(produced_out_ref), error_out(error_out_ref) {} std::span pcm_in = {}; std::span pcm_out = {}; + std::span encoded_tokens_out = {}; + std::span generated_tokens_out = {}; + int32_t &text_token_out; int32_t &sample_count_out; bool &produced_out; emel::error::type &error_out; @@ -65,12 +93,20 @@ struct stream_frame { }; struct flush { - flush(std::span pcm_out_ref, int32_t &sample_count_out_ref, + flush(std::span pcm_out_ref, std::span encoded_tokens_out_ref, + std::span generated_tokens_out_ref, + int32_t &text_token_out_ref, int32_t &sample_count_out_ref, bool &complete_out_ref, emel::error::type &error_out_ref) noexcept - : pcm_out(pcm_out_ref), sample_count_out(sample_count_out_ref), - complete_out(complete_out_ref), error_out(error_out_ref) {} + : pcm_out(pcm_out_ref), encoded_tokens_out(encoded_tokens_out_ref), + generated_tokens_out(generated_tokens_out_ref), + text_token_out(text_token_out_ref), + sample_count_out(sample_count_out_ref), complete_out(complete_out_ref), + error_out(error_out_ref) {} std::span pcm_out = {}; + std::span encoded_tokens_out = {}; + std::span generated_tokens_out = {}; + int32_t &text_token_out; int32_t &sample_count_out; bool &complete_out; emel::error::type &error_out; @@ -84,25 +120,44 @@ struct reset { struct initialize_ctx { emel::error::type err = {}; + emel::error::type child_err = {}; + bool child_accepted = false; }; -struct generate_ctx { +struct condition_ctx { emel::error::type err = {}; + emel::error::type child_err = {}; + emel::error::type graph_err = {}; + bool child_accepted = false; + bool complete = false; + int32_t remaining = -1; }; -struct stream_frame_ctx { +struct generate_ctx { emel::error::type err = {}; }; -struct flush_ctx { +struct frame_ctx { emel::error::type err = {}; + emel::error::type child_err = {}; + emel::error::type graph_err = {}; + bool child_accepted = false; + bool produced = false; + int32_t text_token = -1; }; +struct flush_ctx : frame_ctx {}; + struct initialize_run { const initialize &request; initialize_ctx &ctx; }; +struct condition_run { + const condition &request; + condition_ctx &ctx; +}; + struct generate_run { const generate &request; generate_ctx &ctx; @@ -110,7 +165,7 @@ struct generate_run { struct stream_frame_run { const stream_frame &request; - stream_frame_ctx &ctx; + frame_ctx &ctx; }; struct flush_run { @@ -124,6 +179,8 @@ namespace emel::speech::generator::events { struct initialize_done { const event::initialize &request; + int32_t frame_samples = 0; + int32_t codebook_count = 0; }; struct initialize_error { @@ -131,6 +188,17 @@ struct initialize_error { emel::error::type err = {}; }; +struct condition_done { + const event::condition &request; + bool complete = false; + int32_t remaining = -1; +}; + +struct condition_error { + const event::condition &request; + emel::error::type err = {}; +}; + struct generation_done { const event::generate &request; int32_t sample_count = 0; diff --git a/src/emel/speech/generator/guards.hpp b/src/emel/speech/generator/guards.hpp index ebe0511d..912f5d0b 100644 --- a/src/emel/speech/generator/guards.hpp +++ b/src/emel/speech/generator/guards.hpp @@ -1,79 +1,242 @@ #pragma once +#include + #include "emel/speech/generator/context.hpp" #include "emel/speech/generator/events.hpp" namespace emel::speech::generator::guard { -struct guard_generate_request_valid { +template struct guard_initialize_request_valid { + bool + operator()(const event::initialize_run &, + const action::context &ctx) const noexcept { + const auto count = static_cast(ctx.collaborators.codebook_count); + const auto samples = static_cast(ctx.collaborators.frame_samples); + return ctx.collaborators.codebook_count > 0 && + ctx.collaborators.frame_samples > 0 && + ctx.collaborators.input_codes.size() == count && + ctx.collaborators.output_codes.size() == count && + ctx.collaborators.silence_pcm.size() == samples; + } +}; + +template struct guard_initialize_request_invalid { + bool + operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_initialize_request_valid{}(runtime_ev, + ctx); + } +}; + +template +struct guard_child_succeeded { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0; + } +}; + +template +struct guard_child_failed { + bool + operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_child_succeeded{}( + runtime_ev, ctx); + } +}; + +template struct guard_condition_succeeded_pending { + bool operator()(const event::condition_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && !runtime_ev.ctx.complete; + } +}; + +template struct guard_condition_succeeded_complete { + bool operator()(const event::condition_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && runtime_ev.ctx.complete; + } +}; + +template struct guard_condition_failed { + bool operator()(const event::condition_run &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.ctx.child_accepted || runtime_ev.ctx.child_err != 0 || + runtime_ev.ctx.graph_err != 0; + } +}; + +template struct guard_generate_request_valid { bool operator()(const event::generate_run &runtime_ev, - const action::context &) const noexcept { + const action::context &) const noexcept { return !runtime_ev.request.text.empty() && !runtime_ev.request.pcm_out.empty(); } }; -struct guard_generate_request_invalid { - bool operator()(const event::generate_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_generate_request_valid{}(runtime_ev, ctx); +template struct guard_generate_request_invalid { + bool + operator()(const event::generate_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_generate_request_valid{}(runtime_ev, ctx); } }; -struct guard_stream_request_valid { - bool operator()(const event::stream_frame_run &runtime_ev, - const action::context &) const noexcept { - return !runtime_ev.request.pcm_in.empty() && - !runtime_ev.request.pcm_out.empty(); +template struct guard_stream_request_valid { + bool + operator()(const event::stream_frame_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto count = static_cast(ctx.collaborators.codebook_count); + const auto samples = static_cast(ctx.collaborators.frame_samples); + return runtime_ev.request.pcm_in.size() == samples && + runtime_ev.request.pcm_out.size() >= samples && + runtime_ev.request.encoded_tokens_out.size() >= count && + runtime_ev.request.generated_tokens_out.size() >= count; } }; -struct guard_stream_request_invalid { - bool operator()(const event::stream_frame_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_stream_request_valid{}(runtime_ev, ctx); +template struct guard_stream_request_invalid { + bool + operator()(const event::stream_frame_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_stream_request_valid{}(runtime_ev, ctx); } }; -struct guard_flush_request_valid { - bool operator()(const event::flush_run &runtime_ev, - const action::context &) const noexcept { - return !runtime_ev.request.pcm_out.empty(); +template struct guard_flush_request_valid { + bool + operator()(const event::flush_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto count = static_cast(ctx.collaborators.codebook_count); + const auto samples = static_cast(ctx.collaborators.frame_samples); + return runtime_ev.request.pcm_out.size() >= samples && + runtime_ev.request.encoded_tokens_out.size() >= count && + runtime_ev.request.generated_tokens_out.size() >= count; } }; -struct guard_flush_request_invalid { - bool operator()(const event::flush_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_flush_request_valid{}(runtime_ev, ctx); +template struct guard_flush_request_invalid { + bool + operator()(const event::flush_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_flush_request_valid{}(runtime_ev, ctx); } }; -struct guard_initialize_done_callback_present { - bool operator()(const event::initialize_run &runtime_ev, - const action::context &) const noexcept { +template +struct guard_frame_produced { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && runtime_ev.ctx.produced; + } +}; + +template +struct guard_frame_pending { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0 && !runtime_ev.ctx.produced; + } +}; + +template +struct guard_frame_failed { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return !runtime_ev.ctx.child_accepted || runtime_ev.ctx.child_err != 0 || + runtime_ev.ctx.graph_err != 0; + } +}; + +template +struct guard_done_callback_present { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { return static_cast(runtime_ev.request.on_done); } }; -struct guard_initialize_done_callback_absent { - bool operator()(const event::initialize_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_initialize_done_callback_present{}(runtime_ev, ctx); +template +struct guard_done_callback_absent { + bool + operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_done_callback_present{}(runtime_ev, ctx); } }; -template struct guard_error_callback_present { +template +struct guard_error_callback_present { bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { + const action::context &) const noexcept { return static_cast(runtime_ev.request.on_error); } }; -template struct guard_error_callback_absent { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_error_callback_present{}(runtime_ev, ctx); +template +struct guard_error_callback_absent { + bool + operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_error_callback_present{}(runtime_ev, ctx); + } +}; + +template +struct guard_condition_pending_done_callback_present { + bool + operator()(const event::condition_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_condition_succeeded_pending{}(runtime_ev, + ctx) && + guard_done_callback_present{}(runtime_ev, ctx); + } +}; + +template +struct guard_condition_pending_done_callback_absent { + bool + operator()(const event::condition_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_condition_succeeded_pending{}(runtime_ev, + ctx) && + guard_done_callback_absent{}(runtime_ev, ctx); + } +}; + +template +struct guard_condition_complete_done_callback_present { + bool + operator()(const event::condition_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_condition_succeeded_complete{}(runtime_ev, + ctx) && + guard_done_callback_present{}(runtime_ev, ctx); + } +}; + +template +struct guard_condition_complete_done_callback_absent { + bool + operator()(const event::condition_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_condition_succeeded_complete{}(runtime_ev, + ctx) && + guard_done_callback_absent{}(runtime_ev, ctx); } }; diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index 7f1150aa..095d64b3 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -13,129 +13,283 @@ namespace emel::speech::generator { struct state_uninitialized {}; +struct state_initialize_temporal_result {}; +struct state_initialize_secondary_result {}; +struct state_initialize_encoder_result {}; +struct state_initialize_decoder_result {}; +struct state_initialize_runtime_result {}; +struct state_initialize_predictor_result {}; +struct state_initialize_conditioning_result {}; struct state_initialize_done_channel_decision {}; -struct state_initialize_error_ready_channel_decision {}; -struct state_ready {}; +struct state_initialize_error_channel_decision {}; + +struct state_condition_voice {}; +struct state_condition_voice_result {}; +struct state_condition_prompt_begin_result {}; +struct state_condition_voice_done_channel_decision {}; +struct state_condition_prompt {}; +struct state_condition_prompt_result {}; +struct state_condition_prompt_done_channel_decision {}; +struct state_condition_error_channel_decision {}; +struct state_ready {}; struct state_generate_conditioning {}; struct state_generate_prefill {}; struct state_generate_predict {}; struct state_generate_sample {}; struct state_generate_decode {}; struct state_generate_postprocess {}; -struct state_generate_error_ready_channel_decision {}; -struct state_generate_error_uninitialized_channel_decision {}; -struct state_generate_error_errored_channel_decision {}; +struct state_generate_error_channel_decision {}; -struct state_stream_encode {}; -struct state_stream_tokenize {}; -struct state_stream_prefill {}; -struct state_stream_predict {}; -struct state_stream_sample {}; -struct state_stream_detokenize {}; -struct state_stream_decode {}; -struct state_stream_postprocess {}; -struct state_stream_error_ready_channel_decision {}; -struct state_stream_error_uninitialized_channel_decision {}; -struct state_stream_error_errored_channel_decision {}; +struct state_stream_encode_result {}; +struct state_stream_predict_result {}; +struct state_stream_decode_result {}; +struct state_stream_done_channel_decision {}; +struct state_stream_error_channel_decision {}; -struct state_flush_decode {}; -struct state_flush_postprocess {}; -struct state_flush_error_ready_channel_decision {}; -struct state_flush_error_uninitialized_channel_decision {}; -struct state_flush_error_errored_channel_decision {}; +struct state_flushing {}; +struct state_flush_encode_result {}; +struct state_flush_predict_result {}; +struct state_flush_decode_result {}; +struct state_flush_done_channel_decision {}; +struct state_flush_error_channel_decision {}; struct state_errored {}; /* -generic speech generator scaffold (single source of truth) +generic speech generator (single source of truth) state purpose -- state_ready accepts text-to-speech generation, duplex stream frames, and - decoder flush requests through separate event types so incompatible request - shapes are not representable as one flag-driven payload. -- generate states reserve the text/reference conditioning, prefill, - acoustic-representation prediction, sampling, decoding, and postprocessing - phases used by text/reference synthesis systems. -- stream states reserve the input encode, token alignment, prediction, - sampling, detokenization, streaming decode, and postprocessing phases used - by duplex streaming systems. +- initialization deterministically initializes injected temporal memory, + encoder, decoder, prediction runtime, predictor, and conditioning actors. +- condition states advance reference and prompt conditioning one bounded frame + per public dispatch. +- state_ready accepts offline synthesis or duplex input frames. +- state_flushing advances silence frames through the same encode, predict, and + decode actors without a hidden session loop. control invariants -- the machine contains no model-family names, contracts, routes, constants, or - runtime handler tables. Model-family binding remains outside this component. -- planner, memory, graph, sampler, and kernel actors are injected by reference - and remain independently owned actors. -- every currently uncut phase is explicit in the transition graph. Valid - generation requests finish with cutover_pending rather than silently - succeeding or dispatching the maintained model-family implementation. -- request-local status remains in typed runtime events; context stores only - persistent injected collaborators. - -cutover contract -- each reserved phase will be replaced incrementally by synchronous child - dispatch while preserving this phase order and RTC boundary. -- decoder cadence, streaming versus synthesis input, callback presence, and - request validation remain guard-selected transitions. +- actor and event types are compile-time injected. Generic headers contain no + model-family contracts, handler tables, route callbacks, or runtime type + selection. +- every child result is interpreted by guards and explicit transitions. +- child calls are synchronous, deterministically ordered, and remain inside + the originating RTC boundary. +- request-local status stays in typed runtime events. Context owns only the + persistent injected composition. */ -struct model { +template struct model { auto operator()() const { namespace sml = stateforward::sml; using init_run = event::initialize_run; + using condition_run = event::condition_run; using generate_run = event::generate_run; using stream_run = event::stream_frame_run; using flush_run = event::flush_run; - using init_error_present = guard::guard_error_callback_present; - using init_error_absent = guard::guard_error_callback_absent; + using init_done_present = + guard::guard_done_callback_present; + using init_done_absent = + guard::guard_done_callback_absent; + using init_error_present = + guard::guard_error_callback_present; + using init_error_absent = + guard::guard_error_callback_absent; + using condition_error_present = + guard::guard_error_callback_present; + using condition_error_absent = + guard::guard_error_callback_absent; using generate_error_present = - guard::guard_error_callback_present; + guard::guard_error_callback_present; using generate_error_absent = - guard::guard_error_callback_absent; + guard::guard_error_callback_absent; + using stream_done_present = + guard::guard_done_callback_present; + using stream_done_absent = + guard::guard_done_callback_absent; using stream_error_present = - guard::guard_error_callback_present; - using stream_error_absent = guard::guard_error_callback_absent; - using flush_error_present = guard::guard_error_callback_present; - using flush_error_absent = guard::guard_error_callback_absent; + guard::guard_error_callback_present; + using stream_error_absent = + guard::guard_error_callback_absent; + using flush_done_present = + guard::guard_done_callback_present; + using flush_done_absent = + guard::guard_done_callback_absent; + using flush_error_present = + guard::guard_error_callback_present; + using flush_error_absent = + guard::guard_error_callback_absent; // clang-format off return sml::make_transition_table( //------------------------------------------------------------------------------// - // Construction-time dependency injection makes initialization a pure - // lifecycle transition. Duplicate initialization remains observable. - sml::state <= - *sml::state + sml::event - / action::effect_accept_initialize{} - , sml::state <= - sml::state + sml::event - / action::effect_fail_initialize{} + // Injected actor initialization. + sml::state <= *sml::state + + sml::event [ guard::guard_initialize_request_valid{} ] + / action::effect_initialize_temporal_positions{} + , sml::state <= + sml::state + sml::event + [ guard::guard_initialize_request_invalid{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_secondary_positions{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_encoder{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_decoder{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_runtime{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_predictor{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_conditioning{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} , sml::state <= - sml::state + sml::event - / action::effect_accept_initialize{} - , sml::state <= sml::state - + sml::completion - [ guard::guard_initialize_done_callback_present{} ] - / action::effect_emit_initialize_done{} - , sml::state <= sml::state - + sml::completion - [ guard::guard_initialize_done_callback_absent{} ] + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_initialize_done{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ init_done_present{} ] / action::effect_emit_initialize_done{} + , sml::state <= + sml::state + sml::completion + [ init_done_absent{} ] + , sml::state <= + sml::state + sml::completion + [ init_error_present{} ] / action::effect_emit_initialize_error{} + , sml::state <= + sml::state + sml::completion + [ init_error_absent{} ] + + //------------------------------------------------------------------------------// + // Reference and prompt conditioning, one bounded frame per dispatch. + , sml::state <= sml::state + + sml::event / action::effect_condition_voice{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_condition_succeeded_pending{} ] + / action::effect_publish_condition_pending{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_condition_succeeded_complete{} ] + / action::effect_begin_prompt_conditioning{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_condition_failed{} ] + / action::effect_fail_condition{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_condition_pending{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_condition{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_condition_pending_done_callback_present{} ] + / action::effect_emit_condition_done{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_condition_pending_done_callback_absent{} ] + , sml::state <= + sml::state + + sml::completion + [ guard::guard_condition_complete_done_callback_present{} ] + / action::effect_emit_condition_done{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_condition_complete_done_callback_absent{} ] + , sml::state <= sml::state + + sml::event / action::effect_condition_prompt{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_condition_succeeded_pending{} ] + / action::effect_publish_condition_pending{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_condition_succeeded_complete{} ] + / action::effect_publish_condition_complete{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_condition_failed{} ] + / action::effect_fail_condition{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_condition_pending_done_callback_present{} ] + / action::effect_emit_condition_done{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_condition_pending_done_callback_absent{} ] , sml::state <= - sml::state - + sml::completion [ init_error_present{} ] - / action::effect_emit_initialize_error{} + sml::state + + sml::completion + [ guard::guard_condition_complete_done_callback_present{} ] + / action::effect_emit_condition_done{} , sml::state <= - sml::state - + sml::completion [ init_error_absent{} ] + sml::state + + sml::completion + [ guard::guard_condition_complete_done_callback_absent{} ] + , sml::state <= + sml::state + + sml::completion [ condition_error_present{} ] + / action::effect_emit_condition_error{} + , sml::state <= + sml::state + + sml::completion [ condition_error_absent{} ] //------------------------------------------------------------------------------// - // Text/reference synthesis phase scaffold. + // Offline synthesis remains explicitly reserved for its later cutover. , sml::state <= sml::state - + sml::event [ guard::guard_generate_request_valid{} ] - / action::effect_prepare_generate{} - , sml::state <= - sml::state + sml::event - [ guard::guard_generate_request_invalid{} ] - / action::effect_fail_generate{} + + sml::event [ guard::guard_generate_request_valid{} ] + / action::effect_prepare_generate{} + , sml::state <= sml::state + + sml::event [ guard::guard_generate_request_invalid{} ] + / action::effect_fail_generate{} , sml::state <= sml::state + sml::completion , sml::state <= sml::state @@ -146,167 +300,152 @@ struct model { + sml::completion , sml::state <= sml::state + sml::completion - , sml::state <= + , sml::state <= sml::state + sml::completion - / action::effect_fail_generate{} - , sml::state <= - sml::state + / action::effect_fail_generate{} + , sml::state <= sml::state + sml::completion [ generate_error_present{} ] - / action::effect_emit_generation_error{} - , sml::state <= - sml::state + / action::effect_emit_generation_error{} + , sml::state <= sml::state + sml::completion [ generate_error_absent{} ] //------------------------------------------------------------------------------// - // Duplex streaming phase scaffold. - , sml::state <= sml::state - + sml::event [ guard::guard_stream_request_valid{} ] - / action::effect_prepare_stream_frame{} - , sml::state <= - sml::state + sml::event - [ guard::guard_stream_request_invalid{} ] - / action::effect_fail_stream_frame{} - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= - sml::state + sml::completion - / action::effect_fail_stream_frame{} - , sml::state <= - sml::state + // Duplex encode -> predict -> optional decode. + , sml::state <= sml::state + + sml::event [ guard::guard_stream_request_valid{} ] + / action::effect_encode_stream_frame{} + , sml::state <= sml::state + + sml::event [ guard::guard_stream_request_invalid{} ] + / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_predict_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_produced{} ] + / action::effect_decode_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_frame_pending{} ] + / action::effect_publish_stream_frame_pending{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_frame_failed{} ] + / action::effect_fail_stream_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_stream_frame_produced{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ stream_done_present{} ] + / action::effect_emit_stream_frame_done{} + , sml::state <= sml::state + + sml::completion [ stream_done_absent{} ] + , sml::state <= sml::state + sml::completion [ stream_error_present{} ] - / action::effect_emit_stream_frame_error{} - , sml::state <= - sml::state + / action::effect_emit_stream_frame_error{} + , sml::state <= sml::state + sml::completion [ stream_error_absent{} ] //------------------------------------------------------------------------------// - // Buffered or streaming decoder flush scaffold. - , sml::state <= sml::state - + sml::event [ guard::guard_flush_request_valid{} ] - / action::effect_prepare_flush{} - , sml::state <= - sml::state + sml::event - [ guard::guard_flush_request_invalid{} ] - / action::effect_fail_flush{} - , sml::state <= sml::state - + sml::completion - , sml::state <= - sml::state + sml::completion - / action::effect_fail_flush{} - , sml::state <= - sml::state + // Silence flush uses the same actor pipeline without a hidden loop. + , sml::state <= sml::state + + sml::event [ guard::guard_flush_request_valid{} ] + / action::effect_encode_flush_frame{} + , sml::state <= sml::state + + sml::event [ guard::guard_flush_request_valid{} ] + / action::effect_encode_flush_frame{} + , sml::state <= sml::state + + sml::event [ guard::guard_flush_request_invalid{} ] + / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::event [ guard::guard_flush_request_invalid{} ] + / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_predict_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ guard::guard_frame_produced{} ] + / action::effect_decode_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_frame_pending{} ] + / action::effect_publish_flush_pending{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_frame_failed{} ] + / action::effect_fail_flush{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_flush_produced{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ flush_done_present{} ] + / action::effect_emit_flush_done{} + , sml::state <= sml::state + + sml::completion [ flush_done_absent{} ] + , sml::state <= sml::state + sml::completion [ flush_error_present{} ] - / action::effect_emit_flush_error{} - , sml::state <= - sml::state + / action::effect_emit_flush_error{} + , sml::state <= sml::state + sml::completion [ flush_error_absent{} ] //------------------------------------------------------------------------------// - // Known requests before initialization and after unexpected events. - , sml::state <= - sml::state + sml::event - / action::effect_fail_generate{} - , sml::state <= - sml::state - + sml::completion [ generate_error_present{} ] - / action::effect_emit_generation_error{} - , sml::state <= - sml::state - + sml::completion [ generate_error_absent{} ] - , sml::state <= - sml::state + sml::event - / action::effect_fail_stream_frame{} - , sml::state <= - sml::state - + sml::completion [ stream_error_present{} ] - / action::effect_emit_stream_frame_error{} - , sml::state <= - sml::state - + sml::completion [ stream_error_absent{} ] - , sml::state <= - sml::state + sml::event - / action::effect_fail_flush{} - , sml::state <= - sml::state - + sml::completion [ flush_error_present{} ] - / action::effect_emit_flush_error{} - , sml::state <= - sml::state - + sml::completion [ flush_error_absent{} ] + // Known invalid lifecycle requests and unexpected external events. , sml::state <= sml::state + sml::event - / action::effect_reject{} - - , sml::state <= - sml::state + sml::event - / action::effect_fail_generate{} - , sml::state <= - sml::state - + sml::completion [ generate_error_present{} ] - / action::effect_emit_generation_error{} - , sml::state <= - sml::state - + sml::completion [ generate_error_absent{} ] - , sml::state <= - sml::state + sml::event - / action::effect_fail_stream_frame{} - , sml::state <= - sml::state - + sml::completion [ stream_error_present{} ] - / action::effect_emit_stream_frame_error{} - , sml::state <= - sml::state - + sml::completion [ stream_error_absent{} ] - , sml::state <= - sml::state + sml::event - / action::effect_fail_flush{} - , sml::state <= - sml::state - + sml::completion [ flush_error_present{} ] - / action::effect_emit_flush_error{} - , sml::state <= - sml::state - + sml::completion [ flush_error_absent{} ] - - //------------------------------------------------------------------------------// - // Reset preserves injected collaborators and returns to ready. + / action::effect_reject_reset{} , sml::state <= sml::state - + sml::event / action::effect_reset{} - , sml::state <= sml::state - + sml::event / action::effect_reset{} - - //------------------------------------------------------------------------------// - // Unknown external events are observable through state_errored. + + sml::event + / action::effect_reject_reset{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_reset{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_reset{} , sml::state <= sml::state - + sml::unexpected_event / action::effect_unexpected{} + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} , sml::state <= sml::state - + sml::unexpected_event / action::effect_unexpected{} + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} , sml::state <= sml::state - + sml::unexpected_event / action::effect_unexpected{} + + sml::unexpected_event / action::effect_unexpected{} ); // clang-format on } }; -struct sm : public emel::sm { - using base_type = emel::sm; +template +struct sm : public emel::sm, + action::context> { + using base_type = + emel::sm, action::context>; using base_type::is; using base_type::process_event; using base_type::visit_current_states; - explicit sm(const dependencies &deps) : base_type(std::in_place, deps) {} + explicit sm(const dependencies_type &deps) : base_type(std::in_place, deps) {} bool process_event(const event::initialize &ev) { event::initialize_ctx ctx{}; @@ -315,6 +454,13 @@ struct sm : public emel::sm { return accepted && ctx.err == action::error_code(error::none); } + bool process_event(const event::condition &ev) { + event::condition_ctx ctx{}; + const bool accepted = + base_type::process_event(event::condition_run{ev, ctx}); + return accepted && ctx.err == action::error_code(error::none); + } + bool process_event(const event::generate &ev) { event::generate_ctx ctx{}; const bool accepted = @@ -323,7 +469,7 @@ struct sm : public emel::sm { } bool process_event(const event::stream_frame &ev) { - event::stream_frame_ctx ctx{}; + event::frame_ctx ctx{}; const bool accepted = base_type::process_event(event::stream_frame_run{ev, ctx}); return accepted && ctx.err == action::error_code(error::none); @@ -341,6 +487,9 @@ struct sm : public emel::sm { } }; -using Generator = sm; +template +sm(const dependencies_type &) -> sm; + +template using Generator = sm; } // namespace emel::speech::generator diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index 47c29d8e..00c6032b 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -1,13 +1,14 @@ #include "doctest/doctest.h" +#include #include #include #include #include -#include #include "../../allocation_tracker.hpp" #include "emel/error/error.hpp" +#include "emel/memory/streaming/sm.hpp" #include "emel/speech/generator/sm.hpp" namespace { @@ -15,246 +16,677 @@ namespace { namespace generator = emel::speech::generator; namespace sml = stateforward::sml; -struct callback_capture { - int32_t initialize_done_calls = 0; - int32_t initialize_error_calls = 0; - int32_t generation_error_calls = 0; - int32_t stream_error_calls = 0; - int32_t flush_error_calls = 0; - emel::error::type err = generator::action::error_code(generator::error::none); +struct fake_initialize { + emel::error::type *error_out = nullptr; }; -void record_initialize_done( - callback_capture &capture, - const generator::events::initialize_done &) noexcept { - ++capture.initialize_done_calls; -} +struct fake_voice_condition { + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; + bool *complete_out = nullptr; + int32_t *remaining_frames_out = nullptr; +}; -void record_initialize_error( - callback_capture &capture, - const generator::events::initialize_error &ev) noexcept { - ++capture.initialize_error_calls; - capture.err = ev.err; -} +struct fake_prompt_begin { + emel::error::type *error_out = nullptr; +}; -void record_generation_error( - callback_capture &capture, - const generator::events::generation_error &ev) noexcept { - ++capture.generation_error_calls; - capture.err = ev.err; -} +struct fake_prompt_condition { + int32_t text_token = -1; + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; + bool *complete_out = nullptr; + int32_t *remaining_frames_out = nullptr; +}; -void record_stream_error( - callback_capture &capture, - const generator::events::stream_frame_error &ev) noexcept { - ++capture.stream_error_calls; - capture.err = ev.err; -} +struct fake_encode { + fake_encode(std::span pcm_ref, + std::span tokens_out_ref) noexcept + : pcm(pcm_ref), tokens_out(tokens_out_ref) {} -void record_flush_error(callback_capture &capture, - const generator::events::flush_error &ev) noexcept { - ++capture.flush_error_calls; - capture.err = ev.err; -} + std::span pcm; + std::span tokens_out; + emel::error::type *error_out = nullptr; +}; + +struct fake_predict { + fake_predict(std::span tokens_ref, + std::span tokens_out_ref, + int32_t &text_token_out_ref) noexcept + : tokens(tokens_ref), tokens_out(tokens_out_ref), + text_token_out(text_token_out_ref) {} + + std::span tokens; + std::span tokens_out; + int32_t &text_token_out; + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; + bool *produced_out = nullptr; +}; + +struct fake_decode { + fake_decode(std::span tokens_ref, + std::span pcm_out_ref) noexcept + : tokens(tokens_ref), pcm_out(pcm_out_ref) {} + + std::span tokens; + std::span pcm_out; + emel::error::type *error_out = nullptr; +}; + +struct fake_encoder_actor { + int32_t initialize_calls = 0; + int32_t encode_calls = 0; + bool initialize_accepted = true; + bool encode_accepted = true; + emel::error::type initialize_error = 0; + emel::error::type encode_error = 0; + + bool process_event(const fake_initialize &request) noexcept { + ++initialize_calls; + *request.error_out = initialize_error; + return initialize_accepted; + } + + bool process_event(const fake_encode &request) noexcept { + ++encode_calls; + request.tokens_out[0] = 11; + request.tokens_out[1] = 12; + *request.error_out = encode_error; + return encode_accepted; + } +}; + +struct fake_decoder_actor { + int32_t initialize_calls = 0; + int32_t decode_calls = 0; + bool initialize_accepted = true; + bool decode_accepted = true; + emel::error::type initialize_error = 0; + emel::error::type decode_error = 0; + + bool process_event(const fake_initialize &request) noexcept { + ++initialize_calls; + *request.error_out = initialize_error; + return initialize_accepted; + } + + bool process_event(const fake_decode &request) noexcept { + ++decode_calls; + std::fill(request.pcm_out.begin(), request.pcm_out.end(), 0.25f); + *request.error_out = decode_error; + return decode_accepted; + } +}; + +struct fake_runtime_actor { + int32_t initialize_calls = 0; + bool initialize_accepted = true; + emel::error::type initialize_error = 0; + + bool process_event(const fake_initialize &request) noexcept { + ++initialize_calls; + *request.error_out = initialize_error; + return initialize_accepted; + } +}; + +struct fake_predictor_actor { + int32_t initialize_calls = 0; + int32_t conditioning_initialize_calls = 0; + int32_t voice_condition_calls = 0; + int32_t prompt_begin_calls = 0; + int32_t prompt_condition_calls = 0; + int32_t predict_calls = 0; + int32_t rejected_initialize_call = 0; + bool voice_accepted = true; + bool prompt_begin_accepted = true; + bool prompt_accepted = true; + bool predict_accepted = true; + emel::error::type initialize_error = 0; + emel::error::type voice_error = 0; + emel::error::type voice_graph_error = 0; + emel::error::type prompt_begin_error = 0; + emel::error::type prompt_error = 0; + emel::error::type prompt_graph_error = 0; + emel::error::type predict_error = 0; + emel::error::type predict_graph_error = 0; + bool voice_complete = true; + bool prompt_complete = true; + bool produce = true; + + bool process_event(const fake_initialize &request) noexcept { + ++initialize_calls; + *request.error_out = initialize_error; + return rejected_initialize_call != initialize_calls; + } + + bool process_event(const fake_prompt_begin &request) noexcept { + ++prompt_begin_calls; + *request.error_out = prompt_begin_error; + return prompt_begin_accepted; + } + + bool process_event(const fake_voice_condition &request) noexcept { + ++voice_condition_calls; + *request.error_out = voice_error; + *request.graph_error_out = voice_graph_error; + *request.complete_out = voice_complete; + *request.remaining_frames_out = voice_complete ? 0 : 1; + return voice_accepted; + } + + bool process_event(const fake_prompt_condition &request) noexcept { + ++prompt_condition_calls; + *request.error_out = prompt_error; + *request.graph_error_out = prompt_graph_error; + *request.complete_out = prompt_complete; + *request.remaining_frames_out = prompt_complete ? 0 : 1; + return prompt_accepted; + } + + bool process_event(const fake_predict &request) noexcept { + ++predict_calls; + request.tokens_out[0] = request.tokens[0] + 100; + request.tokens_out[1] = request.tokens[1] + 100; + request.text_token_out = 42; + *request.error_out = predict_error; + *request.graph_error_out = predict_graph_error; + *request.produced_out = produce; + return predict_accepted; + } +}; + +struct fake_dependencies { + using voice_condition_event = fake_voice_condition; + using prompt_begin_event = fake_prompt_begin; + using prompt_condition_event = fake_prompt_condition; + using encode_event = fake_encode; + using predict_event = fake_predict; + using decode_event = fake_decode; + + emel::memory::streaming::sm &temporal_positions; + emel::memory::streaming::sm &secondary_positions; + fake_encoder_actor &encoder; + fake_decoder_actor &decoder; + fake_runtime_actor &runtime; + fake_predictor_actor &predictor; + fake_initialize encoder_initialize = {}; + fake_initialize decoder_initialize = {}; + fake_initialize runtime_initialize = {}; + fake_initialize predictor_initialize = {}; + fake_initialize conditioning_initialize = {}; + std::span silence_pcm = {}; + std::span input_codes = {}; + std::span output_codes = {}; + int32_t frame_samples = 0; + int32_t codebook_count = 0; +}; struct fixture { - emel::batch::planner::sm planner{}; - emel::memory::hybrid::sm memory{}; - emel::graph::sm graph{}; - emel::logits::sampler::sm sampler{}; - emel::kernel::sm kernel{}; - generator::dependencies dependencies{planner, memory, graph, sampler, kernel}; - generator::sm machine{dependencies}; - - bool initialize(callback_capture *capture = nullptr) { + std::array silence{}; + std::array input_codes{}; + std::array output_codes{}; + emel::memory::streaming::sm temporal_positions{ + emel::memory::streaming::dependencies{.capacity = 16}}; + emel::memory::streaming::sm secondary_positions{ + emel::memory::streaming::dependencies{.capacity = 16}}; + fake_encoder_actor encoder{}; + fake_decoder_actor decoder{}; + fake_runtime_actor runtime{}; + fake_predictor_actor predictor{}; + fake_dependencies dependencies; + generator::sm machine; + + explicit fixture(const int32_t frame_samples = 4, + const int32_t codebook_count = 2) + : dependencies{ + .temporal_positions = temporal_positions, + .secondary_positions = secondary_positions, + .encoder = encoder, + .decoder = decoder, + .runtime = runtime, + .predictor = predictor, + .silence_pcm = std::span{silence}, + .input_codes = std::span{input_codes}, + .output_codes = std::span{output_codes}, + .frame_samples = frame_samples, + .codebook_count = codebook_count, + }, + machine{dependencies} {} + + bool initialize() { emel::error::type err = generator::action::error_code(generator::error::none); - generator::event::initialize ev{err}; - if (capture != nullptr) { - ev.on_done = - emel::callback:: - from(capture); - } - return machine.process_event(ev); + return machine.process_event(generator::event::initialize{err}); + } + + bool condition() { + bool complete = false; + int32_t remaining = -1; + emel::error::type err = + generator::action::error_code(generator::error::none); + return machine.process_event( + generator::event::condition{7, complete, remaining, err}); } }; -static_assert(std::is_reference_v); -static_assert(std::is_reference_v); -static_assert(std::is_reference_v); -static_assert(std::is_reference_v); -static_assert(std::is_reference_v); +struct callback_probe { + int32_t done_calls = 0; + int32_t error_calls = 0; + emel::error::type last_error = 0; + + void initialize_done(const generator::events::initialize_done &) noexcept { + ++done_calls; + } + void + initialize_error(const generator::events::initialize_error &ev) noexcept { + ++error_calls; + last_error = ev.err; + } + void condition_done(const generator::events::condition_done &) noexcept { + ++done_calls; + } + void condition_error(const generator::events::condition_error &ev) noexcept { + ++error_calls; + last_error = ev.err; + } + void + generation_error(const generator::events::generation_error &ev) noexcept { + ++error_calls; + last_error = ev.err; + } + void stream_done(const generator::events::stream_frame_done &) noexcept { + ++done_calls; + } + void stream_error(const generator::events::stream_frame_error &ev) noexcept { + ++error_calls; + last_error = ev.err; + } + void flush_done(const generator::events::flush_done &) noexcept { + ++done_calls; + } + void flush_error(const generator::events::flush_error &ev) noexcept { + ++error_calls; + last_error = ev.err; + } +}; + +void advance_to_ready(fixture &test) { + REQUIRE(test.initialize()); + REQUIRE(test.condition()); + REQUIRE(test.condition()); +} } // namespace -TEST_CASE("speech_generator_initializes_with_injected_collaborators") { +TEST_CASE("speech_generator_initializes_injected_actor_composition") { auto test = std::make_unique(); - callback_capture capture{}; - REQUIRE(test->initialize(&capture)); - CHECK(capture.initialize_done_calls == 1); - CHECK(test->machine.is(sml::state)); + REQUIRE(test->initialize()); + CHECK(test->machine.is(sml::state)); + CHECK(test->encoder.initialize_calls == 1); + CHECK(test->decoder.initialize_calls == 1); + CHECK(test->runtime.initialize_calls == 1); + CHECK(test->predictor.initialize_calls == 2); +} - emel::error::type err = generator::action::error_code(generator::error::none); - generator::event::initialize duplicate{err}; - duplicate.on_error = - emel::callback::from< - callback_capture, record_initialize_error>(&capture); - - CHECK_FALSE(test->machine.process_event(duplicate)); - CHECK(err == - generator::action::error_code(generator::error::already_initialized)); - CHECK(capture.initialize_error_calls == 1); - CHECK(capture.err == err); - CHECK(test->machine.is(sml::state)); +TEST_CASE("speech_generator_reports_initialize_outcomes_through_callbacks") { + SUBCASE("success") { + auto test = std::make_unique(); + callback_probe probe{}; + emel::error::type err = -1; + generator::event::initialize request{err}; + request.on_done = decltype(request.on_done)::from< + callback_probe, &callback_probe::initialize_done>(&probe); + + REQUIRE(test->machine.process_event(request)); + CHECK(probe.done_calls == 1); + CHECK(err == generator::action::error_code(generator::error::none)); + } + + SUBCASE("invalid composition") { + auto test = std::make_unique(0, 2); + callback_probe probe{}; + emel::error::type err = 0; + generator::event::initialize request{err}; + request.on_error = decltype(request.on_error)::from< + callback_probe, &callback_probe::initialize_error>(&probe); + + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.error_calls == 1); + CHECK(probe.last_error == + generator::action::error_code(generator::error::invalid_request)); + CHECK(test->machine.is(sml::state)); + } + + SUBCASE("child initialization failure") { + auto test = std::make_unique(); + test->encoder.initialize_error = 9; + callback_probe probe{}; + emel::error::type err = 0; + generator::event::initialize request{err}; + request.on_error = decltype(request.on_error)::from< + callback_probe, &callback_probe::initialize_error>(&probe); + + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.error_calls == 1); + CHECK(probe.last_error == generator::action::error_code( + generator::error::encoder_initialize_failed)); + } } -TEST_CASE("speech_generator_exposes_synthesis_phases_without_hidden_cutover") { +TEST_CASE("speech_generator_conditions_without_model_family_contracts") { auto test = std::make_unique(); REQUIRE(test->initialize()); - std::array reference_pcm{}; - std::array pcm_out{}; - int32_t sample_count = 99; - emel::error::type err = generator::action::error_code(generator::error::none); - callback_capture capture{}; - generator::event::generate generate_ev{"Hello from the generic generator.", - std::span{pcm_out}, - sample_count, err}; - generate_ev.reference_pcm = std::span{reference_pcm}; - generate_ev.on_error = - emel::callback::from< - callback_capture, record_generation_error>(&capture); - - CHECK_FALSE(test->machine.process_event(generate_ev)); - CHECK(err == - generator::action::error_code(generator::error::cutover_pending)); - CHECK(sample_count == 0); - CHECK(capture.generation_error_calls == 1); - CHECK(capture.err == err); + REQUIRE(test->condition()); + CHECK(test->machine.is(sml::state)); + CHECK(test->predictor.voice_condition_calls == 1); + CHECK(test->predictor.prompt_begin_calls == 1); + + REQUIRE(test->condition()); CHECK(test->machine.is(sml::state)); + CHECK(test->predictor.prompt_condition_calls == 1); } -TEST_CASE("speech_generator_exposes_duplex_and_flush_phases") { - auto test = std::make_unique(); - REQUIRE(test->initialize()); +TEST_CASE("speech_generator_models_condition_pending_and_error_results") { + SUBCASE("bounded pending frames") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + callback_probe probe{}; + bool complete = true; + int32_t remaining = -1; + emel::error::type err = 0; + generator::event::condition request{7, complete, remaining, err}; + request.on_done = decltype(request.on_done)::from< + callback_probe, &callback_probe::condition_done>(&probe); + + test->predictor.voice_complete = false; + REQUIRE(test->machine.process_event(request)); + CHECK_FALSE(complete); + CHECK(remaining == 1); + CHECK(probe.done_calls == 1); + CHECK(test->machine.is(sml::state)); + + test->predictor.voice_complete = true; + REQUIRE(test->machine.process_event(request)); + CHECK(probe.done_calls == 2); + CHECK(test->machine.is(sml::state)); + + test->predictor.prompt_complete = false; + REQUIRE(test->machine.process_event(request)); + CHECK_FALSE(complete); + CHECK(probe.done_calls == 3); + + test->predictor.prompt_complete = true; + REQUIRE(test->machine.process_event(request)); + CHECK(complete); + CHECK(probe.done_calls == 4); + CHECK(test->machine.is(sml::state)); + } - std::array pcm_in{}; - std::array pcm_out{}; - int32_t sample_count = 99; - bool produced = true; - emel::error::type err = generator::action::error_code(generator::error::none); - callback_capture capture{}; - generator::event::stream_frame stream_ev{std::span{pcm_in}, - std::span{pcm_out}, - sample_count, produced, err}; - stream_ev.on_error = - emel::callback::from< - callback_capture, record_stream_error>(&capture); - - CHECK_FALSE(test->machine.process_event(stream_ev)); - CHECK(err == - generator::action::error_code(generator::error::cutover_pending)); - CHECK(sample_count == 0); - CHECK_FALSE(produced); - CHECK(capture.stream_error_calls == 1); - CHECK(test->machine.is(sml::state)); + SUBCASE("graph failure") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + test->predictor.voice_graph_error = 7; + callback_probe probe{}; + bool complete = true; + int32_t remaining = 0; + emel::error::type err = 0; + generator::event::condition request{7, complete, remaining, err}; + request.on_error = decltype(request.on_error)::from< + callback_probe, &callback_probe::condition_error>(&probe); + + CHECK_FALSE(test->machine.process_event(request)); + CHECK_FALSE(complete); + CHECK(remaining == -1); + CHECK(probe.error_calls == 1); + CHECK(probe.last_error == + generator::action::error_code(generator::error::conditioning_failed)); + CHECK(test->machine.is(sml::state)); + } +} - sample_count = 99; - bool complete = true; - generator::event::flush flush_ev{std::span{pcm_out}, sample_count, - complete, err}; - flush_ev.on_error = - emel::callback::from< - callback_capture, record_flush_error>(&capture); - - CHECK_FALSE(test->machine.process_event(flush_ev)); - CHECK(err == - generator::action::error_code(generator::error::cutover_pending)); +TEST_CASE("speech_generator_keeps_offline_synthesis_failure_explicit") { + auto test = std::make_unique(); + advance_to_ready(*test); + callback_probe probe{}; + std::array pcm_out{}; + int32_t sample_count = -1; + emel::error::type err = 0; + generator::event::generate request{"hello", std::span{pcm_out}, + sample_count, err}; + request.on_error = decltype(request.on_error)::from< + callback_probe, &callback_probe::generation_error>(&probe); + + CHECK_FALSE(test->machine.process_event(request)); CHECK(sample_count == 0); - CHECK_FALSE(complete); - CHECK(capture.flush_error_calls == 1); + CHECK(probe.error_calls == 1); + CHECK(probe.last_error == + generator::action::error_code(generator::error::cutover_pending)); CHECK(test->machine.is(sml::state)); } -TEST_CASE("speech_generator_rejects_uninitialized_and_invalid_requests") { +TEST_CASE("speech_generator_streams_through_injected_actor_pipeline") { auto test = std::make_unique(); - std::array pcm{}; - int32_t sample_count = 99; + REQUIRE(test->initialize()); + REQUIRE(test->condition()); + REQUIRE(test->condition()); + + std::array pcm_in{}; + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = -1; + int32_t sample_count = 0; + bool produced = false; emel::error::type err = generator::action::error_code(generator::error::none); - generator::event::generate before_initialize{"speech", std::span{pcm}, - sample_count, err}; + generator::event::stream_frame request{std::span{pcm_in}, + std::span{pcm_out}, + std::span{encoded}, + std::span{generated}, + text_token, + sample_count, + produced, + err}; + + REQUIRE(test->machine.process_event(request)); + CHECK(test->machine.is(sml::state)); + CHECK(encoded == std::array{11, 12}); + CHECK(generated == std::array{111, 112}); + CHECK(text_token == 42); + CHECK(sample_count == 4); + CHECK(produced); + CHECK(pcm_out[0] == doctest::Approx(0.25f)); +} - CHECK_FALSE(test->machine.process_event(before_initialize)); - CHECK(err == generator::action::error_code(generator::error::uninitialized)); - CHECK(test->machine.is(sml::state)); +TEST_CASE("speech_generator_streams_pending_frames_and_reports_failures") { + auto test = std::make_unique(); + advance_to_ready(*test); + std::array pcm_in{}; + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = -1; + int32_t sample_count = -1; + bool produced = true; + emel::error::type err = 0; + callback_probe probe{}; + generator::event::stream_frame request{std::span{pcm_in}, + std::span{pcm_out}, + std::span{encoded}, + std::span{generated}, + text_token, + sample_count, + produced, + err}; + + SUBCASE("pending") { + test->predictor.produce = false; + request.on_done = + decltype(request.on_done)::from(&probe); + REQUIRE(test->machine.process_event(request)); + CHECK_FALSE(produced); + CHECK(sample_count == 0); + CHECK(test->decoder.decode_calls == 0); + CHECK(probe.done_calls == 1); + } - generator::event::reset reset_before_initialize{err}; - CHECK_FALSE(test->machine.process_event(reset_before_initialize)); - CHECK(err == generator::action::error_code(generator::error::uninitialized)); - CHECK(test->machine.is(sml::state)); + SUBCASE("invalid request") { + request.pcm_in = request.pcm_in.first(3); + request.on_error = + decltype(request.on_error)::from(&probe); + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.last_error == + generator::action::error_code(generator::error::invalid_request)); + } - REQUIRE(test->initialize()); - generator::event::generate invalid_generate{"", std::span{pcm}, - sample_count, err}; - CHECK_FALSE(test->machine.process_event(invalid_generate)); - CHECK(err == - generator::action::error_code(generator::error::invalid_request)); + SUBCASE("encode failure") { + test->encoder.encode_error = 3; + request.on_error = + decltype(request.on_error)::from(&probe); + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.last_error == + generator::action::error_code(generator::error::encode_failed)); + } - bool produced = true; - generator::event::stream_frame invalid_stream{std::span{}, - std::span{pcm}, - sample_count, produced, err}; - CHECK_FALSE(test->machine.process_event(invalid_stream)); - CHECK(err == - generator::action::error_code(generator::error::invalid_request)); + SUBCASE("predict failure") { + test->predictor.predict_graph_error = 4; + request.on_error = + decltype(request.on_error)::from(&probe); + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.last_error == + generator::action::error_code(generator::error::predict_failed)); + } - bool complete = true; - generator::event::flush invalid_flush{std::span{}, sample_count, - complete, err}; - CHECK_FALSE(test->machine.process_event(invalid_flush)); - CHECK(err == - generator::action::error_code(generator::error::invalid_request)); - CHECK(test->machine.is(sml::state)); + SUBCASE("decode failure") { + test->decoder.decode_accepted = false; + request.on_error = + decltype(request.on_error)::from(&probe); + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.last_error == + generator::action::error_code(generator::error::decode_failed)); + } } -TEST_CASE("speech_generator_reset_recovers_from_unexpected_event") { +TEST_CASE("speech_generator_flushes_silence_through_same_pipeline") { auto test = std::make_unique(); REQUIRE(test->initialize()); + REQUIRE(test->condition()); + REQUIRE(test->condition()); - struct unknown_event {}; - test->machine.process_event(unknown_event{}); - CHECK(test->machine.is(sml::state)); - + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = -1; + int32_t sample_count = 0; + bool complete = true; emel::error::type err = generator::action::error_code(generator::error::none); - generator::event::reset reset_ev{err}; - CHECK(test->machine.process_event(reset_ev)); - CHECK(err == generator::action::error_code(generator::error::none)); - CHECK(test->machine.is(sml::state)); + generator::event::flush request{std::span{pcm_out}, + std::span{encoded}, + std::span{generated}, + text_token, + sample_count, + complete, + err}; + + REQUIRE(test->machine.process_event(request)); + CHECK(test->machine.is(sml::state)); + CHECK(sample_count == 4); + CHECK_FALSE(complete); + CHECK(encoded == std::array{11, 12}); + CHECK(generated == std::array{111, 112}); } -TEST_CASE("speech_generator_scaffold_dispatch_is_allocation_free") { +TEST_CASE("speech_generator_flushes_pending_frames_and_reports_failures") { auto test = std::make_unique(); - REQUIRE(test->initialize()); + advance_to_ready(*test); + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = -1; + int32_t sample_count = -1; + bool complete = true; + emel::error::type err = 0; + callback_probe probe{}; + generator::event::flush request{std::span{pcm_out}, + std::span{encoded}, + std::span{generated}, + text_token, + sample_count, + complete, + err}; + + SUBCASE("pending") { + test->predictor.produce = false; + request.on_done = + decltype(request.on_done)::from(&probe); + REQUIRE(test->machine.process_event(request)); + CHECK(sample_count == 0); + CHECK_FALSE(complete); + CHECK(probe.done_calls == 1); + } - std::array pcm_out{}; + SUBCASE("invalid request") { + request.generated_tokens_out = request.generated_tokens_out.first(1); + request.on_error = + decltype(request.on_error)::from(&probe); + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.last_error == + generator::action::error_code(generator::error::invalid_request)); + } + + SUBCASE("predict failure") { + test->predictor.predict_accepted = false; + request.on_error = + decltype(request.on_error)::from(&probe); + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.last_error == + generator::action::error_code(generator::error::predict_failed)); + } +} + +TEST_CASE("speech_generator_duplex_dispatch_is_allocation_free") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + REQUIRE(test->condition()); + REQUIRE(test->condition()); + + std::array pcm_in{}; + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = -1; int32_t sample_count = 0; + bool produced = false; emel::error::type err = generator::action::error_code(generator::error::none); - generator::event::generate generate_ev{ - "allocation probe", std::span{pcm_out}, sample_count, err}; - bool all_rejected_as_pending = true; - size_t allocation_count = 0u; + generator::event::stream_frame request{std::span{pcm_in}, + std::span{pcm_out}, + std::span{encoded}, + std::span{generated}, + text_token, + sample_count, + produced, + err}; + size_t allocation_count = 0; + bool accepted = true; { emel::test::allocation::allocation_scope allocations; - for (int32_t dispatch = 0; dispatch < 32; ++dispatch) { - all_rejected_as_pending = !test->machine.process_event(generate_ev) && - err == generator::action::error_code( - generator::error::cutover_pending) && - all_rejected_as_pending; + for (int32_t iteration = 0; iteration < 32; ++iteration) { + accepted = test->machine.process_event(request) && accepted; } allocation_count = allocations.allocations(); } - CHECK(all_rejected_as_pending); + CHECK(accepted); CHECK(allocation_count == 0u); } diff --git a/tools/bench/personaplex_compare_tests.cpp b/tools/bench/personaplex_compare_tests.cpp index c6b9f9fd..6a86b9ea 100644 --- a/tools/bench/personaplex_compare_tests.cpp +++ b/tools/bench/personaplex_compare_tests.cpp @@ -120,7 +120,9 @@ TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { "PersonaPlex reference lane\" FORCE)") != std::string::npos); CHECK(emel_source.find("#include layer_offsets = {}; }; +struct cache_binding { + runtime::detail::temporal_kv_view temporal = {}; + runtime::detail::depformer_kv_view secondary = {}; +}; + +bool bind_temporal_cache(void *binding_ptr, const emel::model::data &, + const emel::memory::view::snapshot &, int32_t, + runtime::detail::temporal_kv_view &view) noexcept { + view = static_cast(binding_ptr)->temporal; + return true; +} + +bool bind_secondary_cache(void *binding_ptr, const emel::model::data &, + const emel::memory::view::snapshot &, int32_t, + runtime::detail::depformer_kv_view &view) noexcept { + view = static_cast(binding_ptr)->secondary; + return true; +} + +struct personaplex_dependencies { + using voice_condition_event = predictor::event::prefill_voice; + using prompt_begin_event = predictor::event::begin_personaplex_prompt; + using prompt_condition_event = predictor::event::prefill_personaplex_prompt; + using encode_event = mimi::event::encode_frame; + using predict_event = predictor::event::step; + using decode_event = mimi::event::decode_frame; + + emel::memory::streaming::sm &temporal_positions; + emel::memory::streaming::sm &secondary_positions; + mimi::sm &encoder; + mimi::sm &decoder; + runtime::sm &runtime; + predictor::sm &predictor; + mimi::event::initialize encoder_initialize; + mimi::event::initialize decoder_initialize; + runtime::event::initialize runtime_initialize; + predictor::event::initialize predictor_initialize; + predictor::event::load_voice conditioning_initialize; + std::span silence_pcm = {}; + std::span input_codes = {}; + std::span output_codes = {}; + int32_t frame_samples = 0; + int32_t codebook_count = 0; +}; + bool read_binary_file(const std::filesystem::path &path, std::vector &bytes_out) { std::ifstream file{path, std::ios::binary}; @@ -424,8 +473,14 @@ int main(int argc, char **argv) { std::vector input_codes(static_cast(public_n_q), -1); std::vector output_codes(static_cast(public_n_q), -1); - personaplex_session::dependencies session_dependencies{ - .temporal_kv = + emel::memory::streaming::sm temporal_positions{ + emel::memory::streaming::dependencies{ + .capacity = lm_model.model->moshi_lm.context}}; + emel::memory::streaming::sm secondary_positions{ + emel::memory::streaming::dependencies{ + .capacity = lm_model.model->moshi_lm.depformer_context}}; + cache_binding cache_views{ + .temporal = { .key_cache = std::span{temporal_cache.key_cache}, .value_cache = std::span{temporal_cache.value_cache}, @@ -435,7 +490,7 @@ int main(int argc, char **argv) { .position_capacity = lm_model.model->moshi_lm.context, .kv_dim = lm_model.model->moshi_lm.dim, }, - .depformer_kv = + .secondary = { .key_cache = std::span{depformer_cache.key_cache}, .value_cache = std::span{depformer_cache.value_cache}, @@ -445,65 +500,84 @@ int main(int argc, char **argv) { .position_capacity = lm_model.model->moshi_lm.depformer_context, .kv_dim = lm_model.model->moshi_lm.depformer_dim, }, - .generator_memory = emel::memory::hybrid::kv_binding{}, }; - personaplex_session::sm session{session_dependencies}; - emel::error::type session_err = - emel::error::cast(personaplex_session::error::none); - personaplex_session::event::initialize initialize{ - .mimi_model = *mimi_model.model, - .lm_model = *lm_model.model, - .voice_model = *voice_model.model, - .encoder_storage = - { - .prepared = std::span{encoder_prepared}, - .state = std::span{encoder_state}, - .workspace = std::span{encoder_workspace}, - .frame = std::span{encoder_frame}, - }, - .decoder_storage = - { - .prepared = std::span{decoder_prepared}, - .state = std::span{decoder_state}, - .workspace = std::span{decoder_workspace}, - .frame = std::span{decoder_frame}, - }, - .sampling = - { - .enabled = true, - .consume_forced_text = true, - .audio_temperature = config.audio_temperature, - .text_temperature = config.text_temperature, - .audio_top_k = config.audio_top_k, - .text_top_k = config.text_top_k, - .seed = config.sampling_seed, - }, - .max_blocks = config.max_blocks, - .block_tokens = config.block_tokens, - .error_out = session_err, + runtime::sm prediction_runtime{runtime::bind_kv_caches( + runtime::bind_temporal_kv_cache(&cache_views, bind_temporal_cache), + runtime::bind_depformer_kv_cache(&cache_views, bind_secondary_cache), + temporal_positions, secondary_positions)}; + predictor::sm token_predictor{ + emel::memory::hybrid::kv_binding{}, + runtime::bind_graph_executor(prediction_runtime)}; + mimi::sm encoder{}; + mimi::sm decoder{}; + + runtime::event::initialize runtime_initialize{*lm_model.model}; + runtime_initialize.sampling_enabled = true; + runtime_initialize.sampling_consume_forced_text = true; + runtime_initialize.sampling_audio_temperature = config.audio_temperature; + runtime_initialize.sampling_text_temperature = config.text_temperature; + runtime_initialize.sampling_audio_top_k = config.audio_top_k; + runtime_initialize.sampling_text_top_k = config.text_top_k; + runtime_initialize.sampling_seed = config.sampling_seed; + predictor::event::initialize predictor_initialize{*lm_model.model}; + predictor_initialize.max_blocks = config.max_blocks; + predictor_initialize.block_tokens = config.block_tokens; + + personaplex_dependencies dependencies{ + .temporal_positions = temporal_positions, + .secondary_positions = secondary_positions, + .encoder = encoder, + .decoder = decoder, + .runtime = prediction_runtime, + .predictor = token_predictor, + .encoder_initialize = + mimi::event::initialize{*mimi_model.model, + std::span{encoder_prepared}, + std::span{encoder_state}, + std::span{encoder_workspace}, + std::span{encoder_frame}}, + .decoder_initialize = + mimi::event::initialize{*mimi_model.model, + std::span{decoder_prepared}, + std::span{decoder_state}, + std::span{decoder_workspace}, + std::span{decoder_frame}}, + .runtime_initialize = runtime_initialize, + .predictor_initialize = predictor_initialize, + .conditioning_initialize = + predictor::event::load_voice{*voice_model.model}, + .silence_pcm = std::span{pcm_frame}, + .input_codes = std::span{input_codes}, + .output_codes = std::span{output_codes}, + .frame_samples = frame_samples_i32, + .codebook_count = public_n_q, }; - if (!session.process_event(initialize)) { + generator::sm session{dependencies}; + emel::error::type session_err = + generator::action::error_code(generator::error::none); + if (!session.process_event(generator::event::initialize{session_err})) { std::fprintf(stderr, "PersonaPlex session initialize failed err=%d\n", static_cast(session_err)); return 1; } - while (session.is( - stateforward::sml::state)) { - session_err = emel::error::cast(personaplex_session::error::none); - personaplex_session::event::advance_voice advance{.error_out = session_err}; - (void)session.process_event(advance); + while ( + session.is(stateforward::sml::state)) { + bool complete = false; + int32_t remaining = -1; + session_err = generator::action::error_code(generator::error::none); + (void)session.process_event(generator::event::condition{ + config.prompt_text_token, complete, remaining, session_err}); } - while (session.is( - stateforward::sml::state)) { - session_err = emel::error::cast(personaplex_session::error::none); - personaplex_session::event::advance_prompt advance{ - .text_token = config.prompt_text_token, - .error_out = session_err, - }; - (void)session.process_event(advance); + while ( + session.is(stateforward::sml::state)) { + bool complete = false; + int32_t remaining = -1; + session_err = generator::action::error_code(generator::error::none); + (void)session.process_event(generator::event::condition{ + config.prompt_text_token, complete, remaining, session_err}); } - if (!session.is(stateforward::sml::state)) { + if (!session.is(stateforward::sml::state)) { std::fprintf(stderr, "PersonaPlex prefill failed err=%d\n", static_cast(session_err)); return 1; @@ -516,21 +590,18 @@ int main(int argc, char **argv) { std::copy_n(input_pcm.data() + begin, copy_count, pcm_frame.data()); int32_t text_token = -1; bool produced = false; - session_err = emel::error::cast(personaplex_session::error::none); - personaplex_session::event::live_frame frame{ - .payload = - { - .pcm = std::span{pcm_frame}, - .input_codes_out = std::span{input_codes}, - .output_codes_out = std::span{output_codes}, - .text_token_out = text_token, - .produced_out = produced, - .pcm_out = std::span{output_pcm.data() + - frame_index * frame_samples, - frame_samples}, - }, - .error_out = session_err, - }; + int32_t sample_count = 0; + session_err = generator::action::error_code(generator::error::none); + generator::event::stream_frame frame{ + std::span{pcm_frame}, + std::span{output_pcm.data() + frame_index * frame_samples, + frame_samples}, + std::span{input_codes}, + std::span{output_codes}, + text_token, + sample_count, + produced, + session_err}; (void)session.process_event(frame); std::fprintf(stderr, "EMEL_INPUT frame=%zu codes=", frame_index); for (int32_t index = 0; index < public_n_q; ++index) { @@ -546,30 +617,23 @@ int main(int argc, char **argv) { std::fprintf(stderr, "\n"); } - session_err = emel::error::cast(personaplex_session::error::none); - personaplex_session::event::begin_flush begin_flush{.error_out = session_err}; - (void)session.process_event(begin_flush); std::fill(pcm_frame.begin(), pcm_frame.end(), 0.0f); const size_t flush_steps = config.target_output_frames - input_frames; for (size_t index = 0; index < flush_steps; ++index) { const size_t frame_index = input_frames + index; int32_t text_token = -1; - bool produced = false; - session_err = emel::error::cast(personaplex_session::error::none); - personaplex_session::event::flush_frame frame{ - .payload = - { - .pcm = std::span{pcm_frame}, - .input_codes_out = std::span{input_codes}, - .output_codes_out = std::span{output_codes}, - .text_token_out = text_token, - .produced_out = produced, - .pcm_out = std::span{output_pcm.data() + - frame_index * frame_samples, - frame_samples}, - }, - .error_out = session_err, - }; + int32_t sample_count = 0; + bool complete = false; + session_err = generator::action::error_code(generator::error::none); + generator::event::flush frame{ + std::span{output_pcm.data() + frame_index * frame_samples, + frame_samples}, + std::span{input_codes}, + std::span{output_codes}, + text_token, + sample_count, + complete, + session_err}; (void)session.process_event(frame); std::fprintf(stderr, "EMEL_INPUT frame=%zu codes=", frame_index); for (int32_t codebook = 0; codebook < public_n_q; ++codebook) { @@ -584,9 +648,7 @@ int main(int argc, char **argv) { } std::fprintf(stderr, "\n"); } - personaplex_session::event::finish finish{.error_out = session_err}; - (void)session.process_event(finish); - if (!session.is(stateforward::sml::state)) { + if (!session.is(stateforward::sml::state)) { std::fprintf(stderr, "PersonaPlex session failed err=%d\n", static_cast(session_err)); return 1; From bd6410495247d21c7a4d24e07cb411d757370930 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 17:33:49 -0500 Subject: [PATCH 12/61] refactor: remove obsolete personaplex session actor --- ...ch_generator_moshi_personaplex_session.mmd | 72 --- ...ech_generator_moshi_personaplex_session.md | 154 ------ CMakeLists.txt | 1 - README.md | 1 - .../moshi/personaplex/session/actions.hpp | 337 ------------- .../moshi/personaplex/session/any.hpp | 10 - .../moshi/personaplex/session/context.hpp | 64 --- .../moshi/personaplex/session/errors.hpp | 24 - .../moshi/personaplex/session/events.hpp | 217 -------- .../moshi/personaplex/session/guards.hpp | 184 ------- .../moshi/personaplex/session/sm.hpp | 317 ------------ .../moshi_personaplex_session_tests.cpp | 475 ------------------ 12 files changed, 1856 deletions(-) delete mode 100644 .planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd delete mode 100644 .planning/architecture/speech_generator_moshi_personaplex_session.md delete mode 100644 src/emel/speech/generator/moshi/personaplex/session/actions.hpp delete mode 100644 src/emel/speech/generator/moshi/personaplex/session/any.hpp delete mode 100644 src/emel/speech/generator/moshi/personaplex/session/context.hpp delete mode 100644 src/emel/speech/generator/moshi/personaplex/session/errors.hpp delete mode 100644 src/emel/speech/generator/moshi/personaplex/session/events.hpp delete mode 100644 src/emel/speech/generator/moshi/personaplex/session/guards.hpp delete mode 100644 src/emel/speech/generator/moshi/personaplex/session/sm.hpp delete mode 100644 tests/speech/generator/moshi_personaplex_session_tests.cpp diff --git a/.planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd b/.planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd deleted file mode 100644 index dcbf3044..00000000 --- a/.planning/architecture/mermaid/speech_generator_moshi_personaplex_session.mmd +++ /dev/null @@ -1,72 +0,0 @@ -stateDiagram-v2 - direction TB - [*] --> state_uninitialized - state_uninitialized --> state_initialize_temporal_positions_result : initialize_run [guard_initialize_request_valid_] / effect_initialize_temporal_positions_ - state_initialize_temporal_positions_result --> state_initialize_depformer_positions_result : completion_initialize_run_ [initialize_run__] / effect_initialize_depformer_positions_ - state_initialize_temporal_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ - state_initialize_depformer_positions_result --> state_initialize_encoder_result : completion_initialize_run_ [initialize_run__] / effect_initialize_encoder_ - state_initialize_depformer_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ - state_uninitialized --> state_failed : initialize_run [guard_initialize_request_invalid_] / effect_fail_initialize_invalid_ - state_initialize_encoder_result --> state_initialize_decoder_result : completion_initialize_run_ [guard_encoder_initialize_succeeded_] / effect_initialize_decoder_ - state_initialize_encoder_result --> state_failed : completion_initialize_run_ [guard_encoder_initialize_failed_] / codec_initialize_failed__ - state_initialize_decoder_result --> state_initialize_executor_result : completion_initialize_run_ [initialize_run__] / effect_initialize_executor_ - state_initialize_decoder_result --> state_failed : completion_initialize_run_ [initialize_run__] / codec_initialize_failed__ - state_initialize_executor_result --> state_initialize_generator_result : completion_initialize_run_ [initialize_run__] / effect_initialize_generator_ - state_initialize_executor_result --> state_failed : completion_initialize_run_ [initialize_run__] / executor_initialize_failed__ - state_initialize_generator_result --> state_load_voice_result : completion_initialize_run_ [initialize_run__] / effect_load_voice_ - state_initialize_generator_result --> state_failed : completion_initialize_run_ [initialize_run__] / generator_initialize_failed__ - state_load_voice_result --> state_voice_prefill : completion_initialize_run_ [initialize_run__] / effect_publish_initialize_done_ - state_load_voice_result --> state_failed : completion_initialize_run_ [initialize_run__] / voice_load_failed__ - state_voice_prefill --> state_voice_prefill_result : advance_voice_run [always] / effect_prefill_voice_ - state_voice_prefill_result --> state_voice_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ - state_voice_prefill_result --> state_prompt_begin_result : completion_advance_voice_run_ [advance_voice_run__] / effect_begin_prompt_ - state_voice_prefill_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / voice_prefill_failed__ - state_prompt_begin_result --> state_prompt_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ - state_prompt_begin_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / prompt_begin_failed__ - state_prompt_prefill --> state_prompt_prefill_result : advance_prompt_run [always] / effect_prefill_prompt_ - state_prompt_prefill_result --> state_prompt_prefill : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ - state_prompt_prefill_result --> state_live : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ - state_prompt_prefill_result --> state_failed : completion_advance_prompt_run_ [advance_prompt_run__] / prompt_prefill_failed__ - state_live --> state_live_encode_result : live_frame_run [live_frame_run__] / live_frame_run__ - state_live --> state_failed : live_frame_run [live_frame_run__] / invalid_request__ - state_live_encode_result --> state_live_generate_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_encode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / encode_failed__ - state_live_generate_result --> state_live_decode_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_generate_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_generate_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / generate_failed__ - state_live_decode_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_decode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / decode_failed__ - state_live --> state_flush : begin_flush_run [always] / effect_publish_begin_flush_done_ - state_flush --> state_flush_encode_result : flush_frame_run [flush_frame_run__] / flush_frame_run__ - state_flush --> state_failed : flush_frame_run [flush_frame_run__] / invalid_request__ - state_flush_encode_result --> state_flush_generate_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_encode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / encode_failed__ - state_flush_generate_result --> state_flush_decode_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_generate_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_generate_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / generate_failed__ - state_flush_decode_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_decode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / decode_failed__ - state_flush --> state_done : finish_run [always] / effect_publish_finish_done_ - state_uninitialized --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_temporal_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_depformer_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_encoder_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_decoder_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_executor_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_generator_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_load_voice_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_voice_prefill --> state_failed : _ [always] / effect_mark_unexpected_ - state_voice_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_prompt_begin_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_prompt_prefill --> state_failed : _ [always] / effect_mark_unexpected_ - state_prompt_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_live --> state_failed : _ [always] / effect_mark_unexpected_ - state_live_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_live_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_live_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_done --> state_failed : _ [always] / effect_mark_unexpected_ - state_failed --> state_failed : _ [always] / effect_mark_unexpected_ diff --git a/.planning/architecture/speech_generator_moshi_personaplex_session.md b/.planning/architecture/speech_generator_moshi_personaplex_session.md deleted file mode 100644 index c6846557..00000000 --- a/.planning/architecture/speech_generator_moshi_personaplex_session.md +++ /dev/null @@ -1,154 +0,0 @@ -# speech_generator_moshi_personaplex_session - -Source: [`emel/speech/generator/moshi/personaplex/session/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) - -## Mermaid - -```mermaid -stateDiagram-v2 - direction TB - [*] --> state_uninitialized - state_uninitialized --> state_initialize_temporal_positions_result : initialize_run [guard_initialize_request_valid_] / effect_initialize_temporal_positions_ - state_initialize_temporal_positions_result --> state_initialize_depformer_positions_result : completion_initialize_run_ [initialize_run__] / effect_initialize_depformer_positions_ - state_initialize_temporal_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ - state_initialize_depformer_positions_result --> state_initialize_encoder_result : completion_initialize_run_ [initialize_run__] / effect_initialize_encoder_ - state_initialize_depformer_positions_result --> state_failed : completion_initialize_run_ [initialize_run__] / memory_initialize_failed__ - state_uninitialized --> state_failed : initialize_run [guard_initialize_request_invalid_] / effect_fail_initialize_invalid_ - state_initialize_encoder_result --> state_initialize_decoder_result : completion_initialize_run_ [guard_encoder_initialize_succeeded_] / effect_initialize_decoder_ - state_initialize_encoder_result --> state_failed : completion_initialize_run_ [guard_encoder_initialize_failed_] / codec_initialize_failed__ - state_initialize_decoder_result --> state_initialize_executor_result : completion_initialize_run_ [initialize_run__] / effect_initialize_executor_ - state_initialize_decoder_result --> state_failed : completion_initialize_run_ [initialize_run__] / codec_initialize_failed__ - state_initialize_executor_result --> state_initialize_generator_result : completion_initialize_run_ [initialize_run__] / effect_initialize_generator_ - state_initialize_executor_result --> state_failed : completion_initialize_run_ [initialize_run__] / executor_initialize_failed__ - state_initialize_generator_result --> state_load_voice_result : completion_initialize_run_ [initialize_run__] / effect_load_voice_ - state_initialize_generator_result --> state_failed : completion_initialize_run_ [initialize_run__] / generator_initialize_failed__ - state_load_voice_result --> state_voice_prefill : completion_initialize_run_ [initialize_run__] / effect_publish_initialize_done_ - state_load_voice_result --> state_failed : completion_initialize_run_ [initialize_run__] / voice_load_failed__ - state_voice_prefill --> state_voice_prefill_result : advance_voice_run [always] / effect_prefill_voice_ - state_voice_prefill_result --> state_voice_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ - state_voice_prefill_result --> state_prompt_begin_result : completion_advance_voice_run_ [advance_voice_run__] / effect_begin_prompt_ - state_voice_prefill_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / voice_prefill_failed__ - state_prompt_begin_result --> state_prompt_prefill : completion_advance_voice_run_ [advance_voice_run__] / effect_publish_advance_voice_done_ - state_prompt_begin_result --> state_failed : completion_advance_voice_run_ [advance_voice_run__] / prompt_begin_failed__ - state_prompt_prefill --> state_prompt_prefill_result : advance_prompt_run [always] / effect_prefill_prompt_ - state_prompt_prefill_result --> state_prompt_prefill : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ - state_prompt_prefill_result --> state_live : completion_advance_prompt_run_ [advance_prompt_run__] / effect_publish_advance_prompt_done_ - state_prompt_prefill_result --> state_failed : completion_advance_prompt_run_ [advance_prompt_run__] / prompt_prefill_failed__ - state_live --> state_live_encode_result : live_frame_run [live_frame_run__] / live_frame_run__ - state_live --> state_failed : live_frame_run [live_frame_run__] / invalid_request__ - state_live_encode_result --> state_live_generate_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_encode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / encode_failed__ - state_live_generate_result --> state_live_decode_result : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_generate_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_generate_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / generate_failed__ - state_live_decode_result --> state_live : completion_live_frame_run_ [live_frame_run__] / live_frame_run__ - state_live_decode_result --> state_failed : completion_live_frame_run_ [live_frame_run__] / decode_failed__ - state_live --> state_flush : begin_flush_run [always] / effect_publish_begin_flush_done_ - state_flush --> state_flush_encode_result : flush_frame_run [flush_frame_run__] / flush_frame_run__ - state_flush --> state_failed : flush_frame_run [flush_frame_run__] / invalid_request__ - state_flush_encode_result --> state_flush_generate_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_encode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / encode_failed__ - state_flush_generate_result --> state_flush_decode_result : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_generate_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_generate_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / generate_failed__ - state_flush_decode_result --> state_flush : completion_flush_frame_run_ [flush_frame_run__] / flush_frame_run__ - state_flush_decode_result --> state_failed : completion_flush_frame_run_ [flush_frame_run__] / decode_failed__ - state_flush --> state_done : finish_run [always] / effect_publish_finish_done_ - state_uninitialized --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_temporal_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_depformer_positions_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_encoder_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_decoder_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_executor_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_initialize_generator_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_load_voice_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_voice_prefill --> state_failed : _ [always] / effect_mark_unexpected_ - state_voice_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_prompt_begin_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_prompt_prefill --> state_failed : _ [always] / effect_mark_unexpected_ - state_prompt_prefill_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_live --> state_failed : _ [always] / effect_mark_unexpected_ - state_live_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_live_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_live_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush_encode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush_generate_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_flush_decode_result --> state_failed : _ [always] / effect_mark_unexpected_ - state_done --> state_failed : _ [always] / effect_mark_unexpected_ - state_failed --> state_failed : _ [always] / effect_mark_unexpected_ -``` - -## Transitions - -| Source | Event | Guard | Action | Target | -| --- | --- | --- | --- | --- | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_initialize_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_temporal_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_depformer_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`memory_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_encoder>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`memory_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_initialize_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_fail_initialize_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_encoder_initialize_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_decoder>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`guard_encoder_initialize_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`codec_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_executor>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`codec_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_initialize_generator>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`executor_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_load_voice>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`generator_initialize_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`voice_load_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_prefill_voice>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_begin_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`voice_prefill_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`prompt_begin_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_prefill_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_advance_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`advance_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`prompt_prefill_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`encode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`generate_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`live_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`decode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`begin_flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_begin_flush_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`encode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`generate_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`flush_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`decode_failed>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`finish_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_publish_finish_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_temporal_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_depformer_positions_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_encoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_decoder_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_executor_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_initialize_generator_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_load_voice_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_voice_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_voice_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_begin_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_prompt_prefill_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_live_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_encode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_generate_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_flush_decode_result`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | -| [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | [`state_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/personaplex/session/sm.hpp) | diff --git a/CMakeLists.txt b/CMakeLists.txt index e2ecb517..db328e45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,7 +191,6 @@ if(EMEL_ENABLE_TESTS) tests/speech/generator/lifecycle_tests.cpp tests/speech/generator/moshi_lifecycle_tests.cpp tests/speech/generator/moshi_executor_streaming_tests.cpp - tests/speech/generator/moshi_personaplex_session_tests.cpp tests/speech/encoder/whisper/lifecycle_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp diff --git a/README.md b/README.md index a463e027..08eb17d6 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,6 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/speech_decoder_whisper.md`](.planning/architecture/speech_decoder_whisper.md) - [`.planning/architecture/speech_encoder_whisper.md`](.planning/architecture/speech_encoder_whisper.md) - [`.planning/architecture/speech_generator_moshi_executor.md`](.planning/architecture/speech_generator_moshi_executor.md) -- [`.planning/architecture/speech_generator_moshi_personaplex_session.md`](.planning/architecture/speech_generator_moshi_personaplex_session.md) - [`.planning/architecture/speech_generator_moshi.md`](.planning/architecture/speech_generator_moshi.md) - [`.planning/architecture/speech_generator.md`](.planning/architecture/speech_generator.md) - [`.planning/architecture/speech_tokenizer_moshi.md`](.planning/architecture/speech_tokenizer_moshi.md) diff --git a/src/emel/speech/generator/moshi/personaplex/session/actions.hpp b/src/emel/speech/generator/moshi/personaplex/session/actions.hpp deleted file mode 100644 index 8f9bd06b..00000000 --- a/src/emel/speech/generator/moshi/personaplex/session/actions.hpp +++ /dev/null @@ -1,337 +0,0 @@ -#pragma once - -#include - -#include "emel/speech/generator/moshi/personaplex/session/context.hpp" -#include "emel/speech/generator/moshi/personaplex/session/events.hpp" - -namespace emel::speech::generator::moshi::personaplex::session::action { - -namespace detail_ns { - -inline emel::error::type to_error(const error::code value) noexcept { - return emel::error::cast(value); -} - -template -void effect_store_error(const runtime_event_type &runtime_ev, - const error::code value) noexcept { - runtime_ev.ctx.err = to_error(value); - runtime_ev.request.error_out = runtime_ev.ctx.err; -} - -} // namespace detail_ns - -struct effect_initialize_temporal_positions { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - int32_t error_out = static_cast( - emel::error::cast(emel::memory::streaming::error::none)); - runtime_ev.ctx.child_accepted = ctx.temporal_positions.process_event( - emel::memory::streaming::event::initialize{.error_out = error_out}); - runtime_ev.ctx.child_err = static_cast(error_out); - } -}; - -struct effect_initialize_depformer_positions { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - int32_t error_out = static_cast( - emel::error::cast(emel::memory::streaming::error::none)); - runtime_ev.ctx.child_accepted = ctx.depformer_positions.process_event( - emel::memory::streaming::event::initialize{.error_out = error_out}); - runtime_ev.ctx.child_err = static_cast(error_out); - } -}; - -struct effect_initialize_encoder { - static void effect_capture_codec_initialize( - event::initialize_ctx &runtime, - const mimi::events::initialize_done &done) noexcept { - runtime.frame_samples = done.frame_samples; - runtime.mimi_n_q = done.n_q; - } - - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - mimi::event::initialize request{ - runtime_ev.request.mimi_model, - runtime_ev.request.encoder_storage.prepared, - runtime_ev.request.encoder_storage.state, - runtime_ev.request.encoder_storage.workspace, - runtime_ev.request.encoder_storage.frame}; - request.error_out = &runtime_ev.ctx.child_err; - request.on_done = - emel::callback::from< - event::initialize_ctx, - &effect_initialize_encoder::effect_capture_codec_initialize>( - runtime_ev.ctx); - runtime_ev.ctx.child_accepted = ctx.encoder.process_event(request); - } -}; - -struct effect_initialize_decoder { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - mimi::event::initialize request{ - runtime_ev.request.mimi_model, - runtime_ev.request.decoder_storage.prepared, - runtime_ev.request.decoder_storage.state, - runtime_ev.request.decoder_storage.workspace, - runtime_ev.request.decoder_storage.frame}; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = ctx.decoder.process_event(request); - } -}; - -struct effect_initialize_executor { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - executor::event::initialize request{runtime_ev.request.lm_model}; - request.sampling_enabled = runtime_ev.request.sampling.enabled; - request.sampling_consume_forced_text = - runtime_ev.request.sampling.consume_forced_text; - request.sampling_audio_temperature = - runtime_ev.request.sampling.audio_temperature; - request.sampling_text_temperature = - runtime_ev.request.sampling.text_temperature; - request.sampling_audio_top_k = runtime_ev.request.sampling.audio_top_k; - request.sampling_text_top_k = runtime_ev.request.sampling.text_top_k; - request.sampling_seed = runtime_ev.request.sampling.seed; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = ctx.graph_executor.process_event(request); - } -}; - -struct effect_initialize_generator { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - moshi::event::initialize request{runtime_ev.request.lm_model}; - request.max_blocks = runtime_ev.request.max_blocks; - request.block_tokens = runtime_ev.request.block_tokens; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); - } -}; - -struct effect_load_voice { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - moshi::event::load_voice request{runtime_ev.request.voice_model}; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); - } -}; - -struct effect_publish_initialize_done { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - ctx.frame_samples = runtime_ev.ctx.frame_samples; - ctx.public_n_q = runtime_ev.ctx.mimi_n_q; - runtime_ev.ctx.err = detail_ns::to_error(error::none); - runtime_ev.request.error_out = runtime_ev.ctx.err; - } -}; - -struct effect_fail_initialize_invalid { - void operator()(const event::initialize_run &runtime_ev, - context &) const noexcept { - detail_ns::effect_store_error(runtime_ev, error::invalid_request); - } -}; - -template struct effect_fail_initialize_child { - void operator()(const event::initialize_run &runtime_ev, - context &) const noexcept { - detail_ns::effect_store_error(runtime_ev, error_code); - } -}; - -struct effect_prefill_voice { - void operator()(const event::advance_voice_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - runtime_ev.ctx.graph_err = 0; - runtime_ev.ctx.complete = false; - runtime_ev.ctx.remaining_frames = -1; - moshi::event::prefill_voice request{}; - request.error_out = &runtime_ev.ctx.child_err; - request.graph_error_out = &runtime_ev.ctx.graph_err; - request.complete_out = &runtime_ev.ctx.complete; - request.remaining_frames_out = &runtime_ev.ctx.remaining_frames; - runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); - } -}; - -struct effect_begin_prompt { - void operator()(const event::advance_voice_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - moshi::event::begin_personaplex_prompt request{}; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); - } -}; - -struct effect_publish_advance_voice_done { - void operator()(const event::advance_voice_run &runtime_ev, - context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::none); - runtime_ev.request.error_out = runtime_ev.ctx.err; - } -}; - -template struct effect_fail_advance_voice { - void operator()(const event::advance_voice_run &runtime_ev, - context &) const noexcept { - detail_ns::effect_store_error(runtime_ev, error_code); - } -}; - -struct effect_prefill_prompt { - void operator()(const event::advance_prompt_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - runtime_ev.ctx.graph_err = 0; - runtime_ev.ctx.complete = false; - runtime_ev.ctx.remaining_frames = -1; - moshi::event::prefill_personaplex_prompt request{}; - request.text_token = runtime_ev.request.text_token; - request.error_out = &runtime_ev.ctx.child_err; - request.graph_error_out = &runtime_ev.ctx.graph_err; - request.complete_out = &runtime_ev.ctx.complete; - request.remaining_frames_out = &runtime_ev.ctx.remaining_frames; - runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); - } -}; - -struct effect_publish_advance_prompt_done { - void operator()(const event::advance_prompt_run &runtime_ev, - context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::none); - runtime_ev.request.error_out = runtime_ev.ctx.err; - } -}; - -template struct effect_fail_advance_prompt { - void operator()(const event::advance_prompt_run &runtime_ev, - context &) const noexcept { - detail_ns::effect_store_error(runtime_ev, error_code); - } -}; - -template struct effect_encode_frame { - void operator()(const runtime_event_type &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - mimi::event::encode_frame request{ - runtime_ev.request.payload.pcm, - runtime_ev.request.payload.input_codes_out.first( - static_cast(ctx.public_n_q))}; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = ctx.encoder.process_event(request); - } -}; - -template struct effect_generate_frame { - void operator()(const runtime_event_type &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - runtime_ev.ctx.graph_err = 0; - runtime_ev.ctx.produced = false; - std::fill_n(runtime_ev.request.payload.output_codes_out.data(), - static_cast(ctx.public_n_q), -1); - moshi::event::step request{ - runtime_ev.request.payload.input_codes_out.first( - static_cast(ctx.public_n_q)), - runtime_ev.request.payload.output_codes_out.first( - static_cast(ctx.public_n_q)), - runtime_ev.request.payload.text_token_out}; - request.error_out = &runtime_ev.ctx.child_err; - request.graph_error_out = &runtime_ev.ctx.graph_err; - request.produced_out = &runtime_ev.ctx.produced; - runtime_ev.ctx.child_accepted = ctx.generator.process_event(request); - } -}; - -template struct effect_decode_frame { - void operator()(const runtime_event_type &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - mimi::event::decode_frame request{ - runtime_ev.request.payload.output_codes_out.first( - static_cast(ctx.public_n_q)), - runtime_ev.request.payload.pcm_out}; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = ctx.decoder.process_event(request); - } -}; - -template struct effect_publish_frame_done { - void operator()(const runtime_event_type &runtime_ev, - context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::none); - runtime_ev.request.error_out = runtime_ev.ctx.err; - runtime_ev.request.payload.produced_out = runtime_ev.ctx.produced; - } -}; - -template -struct effect_fail_frame { - void operator()(const runtime_event_type &runtime_ev, - context &) const noexcept { - detail_ns::effect_store_error(runtime_ev, error_code); - runtime_ev.request.payload.produced_out = false; - } -}; - -struct effect_publish_begin_flush_done { - void operator()(const event::begin_flush_run &runtime_ev, - context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::none); - runtime_ev.request.error_out = runtime_ev.ctx.err; - } -}; - -struct effect_fail_begin_flush_invalid { - void operator()(const event::begin_flush_run &runtime_ev, - context &) const noexcept { - detail_ns::effect_store_error(runtime_ev, error::invalid_request); - } -}; - -struct effect_publish_finish_done { - void operator()(const event::finish_run &runtime_ev, - context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::none); - runtime_ev.request.error_out = runtime_ev.ctx.err; - } -}; - -struct effect_fail_finish_invalid { - void operator()(const event::finish_run &runtime_ev, - context &) const noexcept { - detail_ns::effect_store_error(runtime_ev, error::invalid_request); - } -}; - -struct effect_mark_unexpected { - template - void operator()(const unexpected_event_type &runtime_ev, - context &) const noexcept { - if constexpr (requires { - runtime_ev.ctx.err; - runtime_ev.request.error_out; - }) { - runtime_ev.ctx.err = detail_ns::to_error(error::unexpected_event); - runtime_ev.request.error_out = runtime_ev.ctx.err; - } - } -}; - -} // namespace emel::speech::generator::moshi::personaplex::session::action diff --git a/src/emel/speech/generator/moshi/personaplex/session/any.hpp b/src/emel/speech/generator/moshi/personaplex/session/any.hpp deleted file mode 100644 index 70e124e0..00000000 --- a/src/emel/speech/generator/moshi/personaplex/session/any.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "emel/speech/generator/moshi/personaplex/session/sm.hpp" - -namespace emel::speech::generator::moshi::personaplex::session { - -using dependencies = action::dependencies; -using PersonaPlexSession = sm; - -} // namespace emel::speech::generator::moshi::personaplex::session diff --git a/src/emel/speech/generator/moshi/personaplex/session/context.hpp b/src/emel/speech/generator/moshi/personaplex/session/context.hpp deleted file mode 100644 index 56d34d51..00000000 --- a/src/emel/speech/generator/moshi/personaplex/session/context.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "emel/memory/hybrid/context.hpp" -#include "emel/memory/streaming/sm.hpp" -#include "emel/speech/codec/mimi/any.hpp" -#include "emel/speech/generator/moshi/any.hpp" -#include "emel/speech/generator/moshi/executor/any.hpp" - -namespace emel::speech::generator::moshi::personaplex::session::action { - -namespace mimi = emel::speech::codec::mimi; -namespace moshi = emel::speech::generator::moshi; -namespace executor = emel::speech::generator::moshi::executor; - -struct dependencies { - executor::detail::temporal_kv_view temporal_kv = {}; - executor::detail::depformer_kv_view depformer_kv = {}; - emel::memory::hybrid::kv_binding generator_memory = {}; -}; - -struct context { - explicit context(const dependencies &deps) - : temporal_kv(deps.temporal_kv), depformer_kv(deps.depformer_kv), - temporal_positions(emel::memory::streaming::dependencies{ - .capacity = deps.temporal_kv.position_capacity}), - depformer_positions(emel::memory::streaming::dependencies{ - .capacity = deps.depformer_kv.position_capacity}), - graph_executor(executor::bind_kv_caches( - executor::bind_temporal_kv_cache(this, bind_temporal_cache), - executor::bind_depformer_kv_cache(this, bind_depformer_cache), - temporal_positions, depformer_positions)), - generator(deps.generator_memory, - moshi::action::bind_graph_executor( - &graph_executor, executor::dispatch_graph_step)) {} - - static bool - bind_temporal_cache(void *context_ptr, const emel::model::data &, - const emel::memory::view::snapshot &, int32_t, - executor::detail::temporal_kv_view &view) noexcept { - view = static_cast(context_ptr)->temporal_kv; - return true; - } - - static bool - bind_depformer_cache(void *context_ptr, const emel::model::data &, - const emel::memory::view::snapshot &, int32_t, - executor::detail::depformer_kv_view &view) noexcept { - view = static_cast(context_ptr)->depformer_kv; - return true; - } - - executor::detail::temporal_kv_view temporal_kv = {}; - executor::detail::depformer_kv_view depformer_kv = {}; - emel::memory::streaming::sm temporal_positions; - emel::memory::streaming::sm depformer_positions; - int32_t frame_samples = 0; - int32_t public_n_q = 0; - mimi::sm encoder = {}; - mimi::sm decoder = {}; - executor::sm graph_executor; - moshi::sm generator; -}; - -} // namespace emel::speech::generator::moshi::personaplex::session::action diff --git a/src/emel/speech/generator/moshi/personaplex/session/errors.hpp b/src/emel/speech/generator/moshi/personaplex/session/errors.hpp deleted file mode 100644 index 7b17ff7f..00000000 --- a/src/emel/speech/generator/moshi/personaplex/session/errors.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "emel/error/error.hpp" - -namespace emel::speech::generator::moshi::personaplex::session::error { - -enum code : emel::error::type { - none = 0, - invalid_request, - memory_initialize_failed, - codec_initialize_failed, - executor_initialize_failed, - generator_initialize_failed, - voice_load_failed, - voice_prefill_failed, - prompt_begin_failed, - prompt_prefill_failed, - encode_failed, - generate_failed, - decode_failed, - unexpected_event, -}; - -} // namespace emel::speech::generator::moshi::personaplex::session::error diff --git a/src/emel/speech/generator/moshi/personaplex/session/events.hpp b/src/emel/speech/generator/moshi/personaplex/session/events.hpp deleted file mode 100644 index f8d74586..00000000 --- a/src/emel/speech/generator/moshi/personaplex/session/events.hpp +++ /dev/null @@ -1,217 +0,0 @@ -#pragma once - -#include -#include - -#include "emel/error/error.hpp" -#include "emel/model/data.hpp" -#include "emel/speech/generator/moshi/personaplex/session/errors.hpp" - -namespace emel::speech::generator::moshi::personaplex::session::events { - -struct initialize_done; -struct initialize_error; -struct advance_voice_done; -struct advance_voice_error; -struct advance_prompt_done; -struct advance_prompt_error; -struct live_frame_done; -struct live_frame_error; -struct begin_flush_done; -struct begin_flush_error; -struct flush_frame_done; -struct flush_frame_error; -struct finish_done; -struct finish_error; - -} // namespace emel::speech::generator::moshi::personaplex::session::events - -namespace emel::speech::generator::moshi::personaplex::session::event { - -struct codec_storage { - std::span prepared = {}; - std::span state = {}; - std::span workspace = {}; - std::span frame = {}; -}; - -struct sampling_config { - bool enabled = false; - bool consume_forced_text = false; - float audio_temperature = 0.0f; - float text_temperature = 0.0f; - int32_t audio_top_k = 0; - int32_t text_top_k = 0; - uint32_t seed = 0; -}; - -struct initialize { - const emel::model::data &mimi_model; - const emel::model::data &lm_model; - const emel::model::data &voice_model; - codec_storage encoder_storage = {}; - codec_storage decoder_storage = {}; - sampling_config sampling = {}; - int32_t max_blocks = 0; - int32_t block_tokens = 0; - emel::error::type &error_out; -}; - -struct advance_voice { - emel::error::type &error_out; -}; - -struct advance_prompt { - int32_t text_token = -1; - emel::error::type &error_out; -}; - -struct frame_payload { - std::span pcm = {}; - std::span input_codes_out = {}; - std::span output_codes_out = {}; - int32_t &text_token_out; - bool &produced_out; - std::span pcm_out = {}; -}; - -struct live_frame { - frame_payload payload; - emel::error::type &error_out; -}; - -struct begin_flush { - emel::error::type &error_out; -}; - -struct flush_frame { - frame_payload payload; - emel::error::type &error_out; -}; - -struct finish { - emel::error::type &error_out; -}; - -struct initialize_ctx { - emel::error::type err = emel::error::cast(error::none); - emel::error::type child_err = 0; - emel::error::type graph_err = 0; - bool child_accepted = false; - int32_t frame_samples = 0; - int32_t mimi_n_q = 0; -}; - -struct phase_ctx { - emel::error::type err = emel::error::cast(error::none); - emel::error::type child_err = 0; - emel::error::type graph_err = 0; - bool child_accepted = false; - bool complete = false; - int32_t remaining_frames = -1; -}; - -struct frame_ctx { - emel::error::type err = emel::error::cast(error::none); - emel::error::type child_err = 0; - emel::error::type graph_err = 0; - bool child_accepted = false; - bool produced = false; -}; - -struct simple_ctx { - emel::error::type err = emel::error::cast(error::none); -}; - -struct initialize_run { - const initialize &request; - initialize_ctx &ctx; -}; -struct advance_voice_run { - const advance_voice &request; - phase_ctx &ctx; -}; -struct advance_prompt_run { - const advance_prompt &request; - phase_ctx &ctx; -}; -struct live_frame_run { - const live_frame &request; - frame_ctx &ctx; -}; -struct begin_flush_run { - const begin_flush &request; - simple_ctx &ctx; -}; -struct flush_frame_run { - const flush_frame &request; - frame_ctx &ctx; -}; -struct finish_run { - const finish &request; - simple_ctx &ctx; -}; - -} // namespace emel::speech::generator::moshi::personaplex::session::event - -namespace emel::speech::generator::moshi::personaplex::session::events { - -struct initialize_done { - const event::initialize *request = nullptr; - int32_t frame_samples = 0; - int32_t n_q = 0; -}; -struct initialize_error { - const event::initialize *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; -struct advance_voice_done { - const event::advance_voice *request = nullptr; - bool complete = false; - int32_t remaining_frames = -1; -}; -struct advance_voice_error { - const event::advance_voice *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; -struct advance_prompt_done { - const event::advance_prompt *request = nullptr; - bool complete = false; - int32_t remaining_frames = -1; -}; -struct advance_prompt_error { - const event::advance_prompt *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; -struct live_frame_done { - const event::live_frame *request = nullptr; - bool produced = false; -}; -struct live_frame_error { - const event::live_frame *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; -struct begin_flush_done { - const event::begin_flush *request = nullptr; -}; -struct begin_flush_error { - const event::begin_flush *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; -struct flush_frame_done { - const event::flush_frame *request = nullptr; - bool produced = false; -}; -struct flush_frame_error { - const event::flush_frame *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; -struct finish_done { - const event::finish *request = nullptr; -}; -struct finish_error { - const event::finish *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; - -} // namespace emel::speech::generator::moshi::personaplex::session::events diff --git a/src/emel/speech/generator/moshi/personaplex/session/guards.hpp b/src/emel/speech/generator/moshi/personaplex/session/guards.hpp deleted file mode 100644 index ec0ca5ea..00000000 --- a/src/emel/speech/generator/moshi/personaplex/session/guards.hpp +++ /dev/null @@ -1,184 +0,0 @@ -#pragma once - -#include -#include - -#include "emel/speech/generator/moshi/personaplex/session/context.hpp" -#include "emel/speech/generator/moshi/personaplex/session/events.hpp" - -namespace emel::speech::generator::moshi::personaplex::session::guard { - -struct guard_initialize_request_valid { - bool operator()(const event::initialize_run &runtime_ev, - const action::context &ctx) const noexcept { - const auto &request = runtime_ev.request; - const auto &lm = request.lm_model.moshi_lm; - const auto &mimi = request.mimi_model.mimi; - if (lm.num_layers <= 0 || lm.context <= 0 || lm.dim <= 0 || - lm.depformer_num_layers <= 0 || lm.depformer_context <= 0 || - lm.depformer_dim <= 0 || lm.inference_dep_q <= 0 || mimi.n_q <= 0 || - lm.card <= 0 || mimi.card <= 0) { - return false; - } - const size_t temporal_layers = static_cast(lm.num_layers); - const size_t temporal_context = static_cast(lm.context); - const size_t depformer_layers = - static_cast(lm.depformer_num_layers); - const size_t depformer_context = static_cast(lm.depformer_context); - if (temporal_context > - std::numeric_limits::max() / temporal_layers || - static_cast(lm.dim) > - std::numeric_limits::max() / - (temporal_layers * temporal_context) || - depformer_context > - std::numeric_limits::max() / depformer_layers || - static_cast(lm.depformer_dim) > - std::numeric_limits::max() / - (depformer_layers * depformer_context)) { - return false; - } - const size_t temporal_elements = - temporal_layers * temporal_context * static_cast(lm.dim); - const size_t depformer_elements = depformer_layers * depformer_context * - static_cast(lm.depformer_dim); - return request.sampling.enabled && request.sampling.consume_forced_text && - request.sampling.audio_temperature > 0.0f && - request.sampling.text_temperature > 0.0f && - request.sampling.audio_top_k > 0 && - request.sampling.text_top_k > 0 && request.sampling.seed != 0u && - request.max_blocks > 0 && request.block_tokens > 0 && - lm.inference_dep_q == mimi.n_q && lm.card == mimi.card && - ctx.temporal_kv.key_cache.data() != nullptr && - ctx.temporal_kv.value_cache.data() != nullptr && - ctx.temporal_kv.key_cache.size() >= temporal_elements && - ctx.temporal_kv.value_cache.size() >= temporal_elements && - ctx.temporal_kv.layer_cache_offsets.size() >= - static_cast(lm.num_layers) && - ctx.temporal_kv.layer_count == lm.num_layers && - ctx.temporal_kv.position_capacity == lm.context && - ctx.temporal_kv.kv_dim == lm.dim && - ctx.depformer_kv.key_cache.data() != nullptr && - ctx.depformer_kv.value_cache.data() != nullptr && - ctx.depformer_kv.key_cache.size() >= depformer_elements && - ctx.depformer_kv.value_cache.size() >= depformer_elements && - ctx.depformer_kv.layer_cache_offsets.size() >= - static_cast(lm.depformer_num_layers) && - ctx.depformer_kv.layer_count == lm.depformer_num_layers && - ctx.depformer_kv.position_capacity == lm.depformer_context && - ctx.depformer_kv.kv_dim == lm.depformer_dim; - } -}; - -struct guard_initialize_request_invalid { - bool operator()(const event::initialize_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_initialize_request_valid{}(runtime_ev, ctx); - } -}; - -struct guard_encoder_initialize_succeeded { - bool operator()(const event::initialize_run &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && - runtime_ev.ctx.frame_samples > 0 && runtime_ev.ctx.mimi_n_q > 0 && - runtime_ev.ctx.mimi_n_q == - runtime_ev.request.lm_model.moshi_lm.inference_dep_q; - } -}; - -struct guard_encoder_initialize_failed { - bool operator()(const event::initialize_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_encoder_initialize_succeeded{}(runtime_ev, ctx); - } -}; - -template struct guard_child_succeeded { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0; - } -}; - -template struct guard_child_failed { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_child_succeeded{}(runtime_ev, ctx); - } -}; - -template struct guard_phase_succeeded_incomplete { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && - runtime_ev.ctx.graph_err == 0 && !runtime_ev.ctx.complete; - } -}; - -template struct guard_phase_succeeded_complete { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && - runtime_ev.ctx.graph_err == 0 && runtime_ev.ctx.complete; - } -}; - -template struct guard_phase_failed { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { - return !runtime_ev.ctx.child_accepted || runtime_ev.ctx.child_err != 0 || - runtime_ev.ctx.graph_err != 0; - } -}; - -template struct guard_frame_request_valid { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &ctx) const noexcept { - const auto &request = runtime_ev.request; - const auto &payload = request.payload; - return payload.pcm.data() != nullptr && - payload.input_codes_out.data() != nullptr && - payload.output_codes_out.data() != nullptr && - payload.pcm_out.data() != nullptr && - payload.pcm.size() == static_cast(ctx.frame_samples) && - payload.input_codes_out.size() >= - static_cast(ctx.public_n_q) && - payload.output_codes_out.size() >= - static_cast(ctx.public_n_q) && - payload.pcm_out.size() >= static_cast(ctx.frame_samples); - } -}; - -template struct guard_frame_request_invalid { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_frame_request_valid{}(runtime_ev, ctx); - } -}; - -template struct guard_frame_generated_and_produced { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && - runtime_ev.ctx.graph_err == 0 && runtime_ev.ctx.produced; - } -}; - -template -struct guard_frame_generated_without_output { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && - runtime_ev.ctx.graph_err == 0 && !runtime_ev.ctx.produced; - } -}; - -template struct guard_frame_generate_failed { - bool operator()(const runtime_event_type &runtime_ev, - const action::context &) const noexcept { - return !runtime_ev.ctx.child_accepted || runtime_ev.ctx.child_err != 0 || - runtime_ev.ctx.graph_err != 0; - } -}; - -} // namespace emel::speech::generator::moshi::personaplex::session::guard diff --git a/src/emel/speech/generator/moshi/personaplex/session/sm.hpp b/src/emel/speech/generator/moshi/personaplex/session/sm.hpp deleted file mode 100644 index 9bb66f38..00000000 --- a/src/emel/speech/generator/moshi/personaplex/session/sm.hpp +++ /dev/null @@ -1,317 +0,0 @@ -#pragma once -// benchmark: designed - -#include - -#include "emel/sm.hpp" -#include "emel/speech/generator/moshi/personaplex/session/actions.hpp" -#include "emel/speech/generator/moshi/personaplex/session/context.hpp" -#include "emel/speech/generator/moshi/personaplex/session/events.hpp" -#include "emel/speech/generator/moshi/personaplex/session/guards.hpp" - -namespace emel::speech::generator::moshi::personaplex::session { - -struct state_uninitialized {}; -struct state_initialize_temporal_positions_result {}; -struct state_initialize_depformer_positions_result {}; -struct state_initialize_encoder_result {}; -struct state_initialize_decoder_result {}; -struct state_initialize_executor_result {}; -struct state_initialize_generator_result {}; -struct state_load_voice_result {}; -struct state_voice_prefill {}; -struct state_voice_prefill_result {}; -struct state_prompt_begin_result {}; -struct state_prompt_prefill {}; -struct state_prompt_prefill_result {}; -struct state_live {}; -struct state_live_encode_result {}; -struct state_live_generate_result {}; -struct state_live_decode_result {}; -struct state_flush {}; -struct state_flush_encode_result {}; -struct state_flush_generate_result {}; -struct state_flush_decode_result {}; -struct state_done {}; -struct state_failed {}; - -struct model { - auto operator()() const { - namespace sml = stateforward::sml; - using init_run = event::initialize_run; - using voice_run = event::advance_voice_run; - using prompt_run = event::advance_prompt_run; - using live_run = event::live_frame_run; - using begin_flush_run = event::begin_flush_run; - using flush_run = event::flush_frame_run; - using finish_run = event::finish_run; - - // clang-format off - return sml::make_transition_table( - //------------------------------------------------------------------------------// - // Initialize every child actor in deterministic RTC order. - sml::state <= *sml::state - + sml::event [ guard::guard_initialize_request_valid{} ] - / action::effect_initialize_temporal_positions{} - , sml::state <= - sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_initialize_depformer_positions{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_initialize_child{} - , sml::state <= - sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_initialize_encoder{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_initialize_child{} - , sml::state <= sml::state - + sml::event [ guard::guard_initialize_request_invalid{} ] - / action::effect_fail_initialize_invalid{} - , sml::state <= sml::state - + sml::completion [ guard::guard_encoder_initialize_succeeded{} ] - / action::effect_initialize_decoder{} - , sml::state <= sml::state - + sml::completion [ guard::guard_encoder_initialize_failed{} ] - / action::effect_fail_initialize_child{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_initialize_executor{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_initialize_child{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_initialize_generator{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_initialize_child{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_load_voice{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_initialize_child{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_publish_initialize_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_initialize_child{} - - //------------------------------------------------------------------------------// - // Voice and empty/system prompt prefill phases. - , sml::state <= sml::state - + sml::event / action::effect_prefill_voice{} - , sml::state <= sml::state - + sml::completion [ guard::guard_phase_succeeded_incomplete{} ] - / action::effect_publish_advance_voice_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_phase_succeeded_complete{} ] - / action::effect_begin_prompt{} - , sml::state <= sml::state - + sml::completion [ guard::guard_phase_failed{} ] - / action::effect_fail_advance_voice{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_publish_advance_voice_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_advance_voice{} - , sml::state <= sml::state - + sml::event / action::effect_prefill_prompt{} - , sml::state <= sml::state - + sml::completion [ guard::guard_phase_succeeded_incomplete{} ] - / action::effect_publish_advance_prompt_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_phase_succeeded_complete{} ] - / action::effect_publish_advance_prompt_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_phase_failed{} ] - / action::effect_fail_advance_prompt{} - - //------------------------------------------------------------------------------// - // Live input frames. Produced/decode selection is explicit. - , sml::state <= sml::state - + sml::event [ guard::guard_frame_request_valid{} ] - / action::effect_encode_frame{} - , sml::state <= sml::state - + sml::event [ guard::guard_frame_request_invalid{} ] - / action::effect_fail_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_generate_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_frame_generated_and_produced{} ] - / action::effect_decode_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_frame_generated_without_output{} ] - / action::effect_publish_frame_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_frame_generate_failed{} ] - / action::effect_fail_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_publish_frame_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_frame{} - - //------------------------------------------------------------------------------// - // Explicit silence flush and terminal phases. - , sml::state <= sml::state - + sml::event / action::effect_publish_begin_flush_done{} - , sml::state <= sml::state - + sml::event [ guard::guard_frame_request_valid{} ] - / action::effect_encode_frame{} - , sml::state <= sml::state - + sml::event [ guard::guard_frame_request_invalid{} ] - / action::effect_fail_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_generate_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_frame_generated_and_produced{} ] - / action::effect_decode_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_frame_generated_without_output{} ] - / action::effect_publish_frame_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_frame_generate_failed{} ] - / action::effect_fail_frame{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_publish_frame_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_child_failed{} ] - / action::effect_fail_frame{} - , sml::state <= sml::state - + sml::event / action::effect_publish_finish_done{} - - //------------------------------------------------------------------------------// - // Every external event outside its modeled phase is explicit. - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - , sml::state <= sml::state - + sml::unexpected_event / action::effect_mark_unexpected{} - ); - // clang-format on - } -}; - -struct sm : public emel::sm { - using base_type = emel::sm; - using base_type::is; - using base_type::visit_current_states; - - explicit sm(const action::dependencies &deps) - : base_type(std::in_place, deps) {} - - sm(const sm &) = delete; - sm &operator=(const sm &) = delete; - sm(sm &&) = delete; - sm &operator=(sm &&) = delete; - - bool process_event(const event::initialize &request) { - event::initialize_ctx ctx{}; - event::initialize_run runtime_ev{request, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } - - bool process_event(const event::advance_voice &request) { - event::phase_ctx ctx{}; - event::advance_voice_run runtime_ev{request, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } - - bool process_event(const event::advance_prompt &request) { - event::phase_ctx ctx{}; - event::advance_prompt_run runtime_ev{request, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } - - bool process_event(const event::live_frame &request) { - event::frame_ctx ctx{}; - event::live_frame_run runtime_ev{request, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } - - bool process_event(const event::begin_flush &request) { - event::simple_ctx ctx{}; - event::begin_flush_run runtime_ev{request, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } - - bool process_event(const event::flush_frame &request) { - event::frame_ctx ctx{}; - event::flush_frame_run runtime_ev{request, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } - - bool process_event(const event::finish &request) { - event::simple_ctx ctx{}; - event::finish_run runtime_ev{request, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } -}; - -using Session = sm; - -} // namespace emel::speech::generator::moshi::personaplex::session diff --git a/tests/speech/generator/moshi_personaplex_session_tests.cpp b/tests/speech/generator/moshi_personaplex_session_tests.cpp deleted file mode 100644 index 813d2438..00000000 --- a/tests/speech/generator/moshi_personaplex_session_tests.cpp +++ /dev/null @@ -1,475 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "emel/model/data.hpp" -#include "emel/speech/codec/mimi/any.hpp" -#include "emel/speech/generator/moshi/personaplex/session/any.hpp" -#include "moshi_fixture.hpp" - -TEST_CASE("PersonaPlex session runs its injected actors end to end") { - namespace mimi = emel::speech::codec::mimi; - namespace personaplex = emel::speech::generator::moshi::personaplex::session; - namespace sml = stateforward::sml; - using emel::speech::generator::moshi::test::load_fixture_or_skip; - - auto codec = load_fixture_or_skip("mimi-tiny.gguf"); - auto lm = load_fixture_or_skip("moshi-tiny-lm.gguf"); - auto voice = load_fixture_or_skip("moshi-tiny-voice.gguf"); - if (codec.model == nullptr || lm.model == nullptr || voice.model == nullptr) { - return; - } - - std::vector encoder_prepared( - mimi::prepared_arena_floats(*codec.model)); - std::vector encoder_state(mimi::state_arena_floats(*codec.model)); - std::vector encoder_workspace( - mimi::workspace_arena_floats(*codec.model)); - std::vector encoder_frame(mimi::frame_arena_floats(*codec.model)); - std::vector decoder_prepared( - mimi::prepared_arena_floats(*codec.model)); - std::vector decoder_state(mimi::state_arena_floats(*codec.model)); - std::vector decoder_workspace( - mimi::workspace_arena_floats(*codec.model)); - std::vector decoder_frame(mimi::frame_arena_floats(*codec.model)); - - auto &lm_config = lm.model->moshi_lm; - const size_t temporal_per_layer = static_cast(lm_config.context) * - static_cast(lm_config.dim); - std::vector temporal_keys( - static_cast(lm_config.num_layers) * temporal_per_layer, 0u); - std::vector temporal_values(temporal_keys.size(), 0u); - std::vector temporal_offsets( - static_cast(lm_config.num_layers), 0u); - for (int32_t layer = 0; layer < lm_config.num_layers; ++layer) { - temporal_offsets[static_cast(layer)] = - static_cast(layer) * temporal_per_layer; - } - const size_t depformer_per_layer = - static_cast(lm_config.depformer_context) * - static_cast(lm_config.depformer_dim); - std::vector depformer_keys( - static_cast(lm_config.depformer_num_layers) * depformer_per_layer, - 0u); - std::vector depformer_values(depformer_keys.size(), 0u); - std::vector depformer_offsets( - static_cast(lm_config.depformer_num_layers), 0u); - for (int32_t layer = 0; layer < lm_config.depformer_num_layers; ++layer) { - depformer_offsets[static_cast(layer)] = - static_cast(layer) * depformer_per_layer; - } - personaplex::dependencies dependencies{ - .temporal_kv = - { - .key_cache = std::span{temporal_keys}, - .value_cache = std::span{temporal_values}, - .layer_cache_offsets = std::span{temporal_offsets}, - .layer_count = lm_config.num_layers, - .position_capacity = lm_config.context, - .kv_dim = lm_config.dim, - }, - .depformer_kv = - { - .key_cache = std::span{depformer_keys}, - .value_cache = std::span{depformer_values}, - .layer_cache_offsets = std::span{depformer_offsets}, - .layer_count = lm_config.depformer_num_layers, - .position_capacity = lm_config.depformer_context, - .kv_dim = lm_config.depformer_dim, - }, - }; - personaplex::sm session{dependencies}; - emel::error::type err = emel::error::cast(personaplex::error::none); - personaplex::event::initialize initialize{ - .mimi_model = *codec.model, - .lm_model = *lm.model, - .voice_model = *voice.model, - .encoder_storage = - { - .prepared = std::span{encoder_prepared}, - .state = std::span{encoder_state}, - .workspace = std::span{encoder_workspace}, - .frame = std::span{encoder_frame}, - }, - .decoder_storage = - { - .prepared = std::span{decoder_prepared}, - .state = std::span{decoder_state}, - .workspace = std::span{decoder_workspace}, - .frame = std::span{decoder_frame}, - }, - .sampling = - { - .enabled = true, - .consume_forced_text = true, - .audio_temperature = 0.8f, - .text_temperature = 0.7f, - .audio_top_k = 250, - .text_top_k = 25, - .seed = 1234, - }, - .max_blocks = 16, - .block_tokens = 4, - .error_out = err, - }; - - auto guard_context = - std::make_unique(dependencies); - personaplex::event::initialize_ctx initialize_ctx{}; - personaplex::event::initialize_run initialize_run{initialize, initialize_ctx}; - const auto request_is_valid = [&] { - return personaplex::guard::guard_initialize_request_valid{}(initialize_run, - *guard_context); - }; - REQUIRE(request_is_valid()); - - const int32_t temporal_layer_count = lm_config.num_layers; - lm_config.num_layers = 0; - CHECK_FALSE(request_is_valid()); - lm_config.num_layers = temporal_layer_count; - const int32_t temporal_context_size = lm_config.context; - lm_config.context = 0; - CHECK_FALSE(request_is_valid()); - lm_config.context = temporal_context_size; - const int32_t temporal_dimension = lm_config.dim; - lm_config.dim = 0; - CHECK_FALSE(request_is_valid()); - lm_config.dim = temporal_dimension; - const int32_t depformer_layer_count = lm_config.depformer_num_layers; - lm_config.depformer_num_layers = 0; - CHECK_FALSE(request_is_valid()); - lm_config.depformer_num_layers = depformer_layer_count; - const int32_t depformer_context_size = lm_config.depformer_context; - lm_config.depformer_context = 0; - CHECK_FALSE(request_is_valid()); - lm_config.depformer_context = depformer_context_size; - const int32_t depformer_dimension = lm_config.depformer_dim; - lm_config.depformer_dim = 0; - CHECK_FALSE(request_is_valid()); - lm_config.depformer_dim = depformer_dimension; - const int32_t inference_dep_q = lm_config.inference_dep_q; - lm_config.inference_dep_q = 0; - CHECK_FALSE(request_is_valid()); - lm_config.inference_dep_q = inference_dep_q; - const int32_t codec_n_q = codec.model->mimi.n_q; - codec.model->mimi.n_q = 0; - CHECK_FALSE(request_is_valid()); - codec.model->mimi.n_q = codec_n_q; - const int32_t lm_card = lm_config.card; - lm_config.card = 0; - CHECK_FALSE(request_is_valid()); - lm_config.card = lm_card; - const int32_t codec_card = codec.model->mimi.card; - codec.model->mimi.card = 0; - CHECK_FALSE(request_is_valid()); - codec.model->mimi.card = codec_card; - - initialize.sampling.enabled = false; - CHECK_FALSE(request_is_valid()); - initialize.sampling.enabled = true; - initialize.sampling.consume_forced_text = false; - CHECK_FALSE(request_is_valid()); - initialize.sampling.consume_forced_text = true; - initialize.sampling.audio_temperature = 0.0f; - CHECK_FALSE(request_is_valid()); - initialize.sampling.audio_temperature = 0.8f; - initialize.sampling.text_temperature = 0.0f; - CHECK_FALSE(request_is_valid()); - initialize.sampling.text_temperature = 0.7f; - initialize.sampling.audio_top_k = 0; - CHECK_FALSE(request_is_valid()); - initialize.sampling.audio_top_k = 250; - initialize.sampling.text_top_k = 0; - CHECK_FALSE(request_is_valid()); - initialize.sampling.text_top_k = 25; - initialize.sampling.seed = 0; - CHECK_FALSE(request_is_valid()); - initialize.sampling.seed = 1234; - initialize.max_blocks = 0; - CHECK_FALSE(request_is_valid()); - initialize.max_blocks = 16; - initialize.block_tokens = 0; - CHECK_FALSE(request_is_valid()); - initialize.block_tokens = 4; - - lm_config.inference_dep_q = inference_dep_q + 1; - CHECK_FALSE(request_is_valid()); - lm_config.inference_dep_q = inference_dep_q; - lm_config.card = lm_card + 1; - CHECK_FALSE(request_is_valid()); - lm_config.card = lm_card; - - const auto temporal_key_view = guard_context->temporal_kv.key_cache; - guard_context->temporal_kv.key_cache = {}; - CHECK_FALSE(request_is_valid()); - guard_context->temporal_kv.key_cache = temporal_key_view; - const auto temporal_value_view = guard_context->temporal_kv.value_cache; - guard_context->temporal_kv.value_cache = {}; - CHECK_FALSE(request_is_valid()); - guard_context->temporal_kv.value_cache = temporal_value_view; - const auto temporal_layer_views = - guard_context->temporal_kv.layer_cache_offsets; - guard_context->temporal_kv.layer_cache_offsets = {}; - CHECK_FALSE(request_is_valid()); - guard_context->temporal_kv.layer_cache_offsets = temporal_layer_views; - --guard_context->temporal_kv.layer_count; - CHECK_FALSE(request_is_valid()); - ++guard_context->temporal_kv.layer_count; - --guard_context->temporal_kv.position_capacity; - CHECK_FALSE(request_is_valid()); - ++guard_context->temporal_kv.position_capacity; - --guard_context->temporal_kv.kv_dim; - CHECK_FALSE(request_is_valid()); - ++guard_context->temporal_kv.kv_dim; - - const auto depformer_key_view = guard_context->depformer_kv.key_cache; - guard_context->depformer_kv.key_cache = {}; - CHECK_FALSE(request_is_valid()); - guard_context->depformer_kv.key_cache = depformer_key_view; - const auto depformer_value_view = guard_context->depformer_kv.value_cache; - guard_context->depformer_kv.value_cache = {}; - CHECK_FALSE(request_is_valid()); - guard_context->depformer_kv.value_cache = depformer_value_view; - const auto depformer_layer_views = - guard_context->depformer_kv.layer_cache_offsets; - guard_context->depformer_kv.layer_cache_offsets = {}; - CHECK_FALSE(request_is_valid()); - guard_context->depformer_kv.layer_cache_offsets = depformer_layer_views; - --guard_context->depformer_kv.layer_count; - CHECK_FALSE(request_is_valid()); - ++guard_context->depformer_kv.layer_count; - --guard_context->depformer_kv.position_capacity; - CHECK_FALSE(request_is_valid()); - ++guard_context->depformer_kv.position_capacity; - --guard_context->depformer_kv.kv_dim; - CHECK_FALSE(request_is_valid()); - ++guard_context->depformer_kv.kv_dim; - guard_context.reset(); - - REQUIRE(session.process_event(initialize)); - - for (int32_t step = 0; - step < 16 && session.is(sml::state); - ++step) { - personaplex::event::advance_voice advance{.error_out = err}; - REQUIRE(session.process_event(advance)); - } - for (int32_t step = 0; - step < 16 && session.is(sml::state); - ++step) { - personaplex::event::advance_prompt advance{ - .text_token = -1, - .error_out = err, - }; - REQUIRE(session.process_event(advance)); - } - REQUIRE(session.is(sml::state)); - - const int32_t frame_samples = static_cast( - std::lround(static_cast(codec.model->mimi.sample_rate) / - static_cast(codec.model->mimi.frame_rate))); - const int32_t public_n_q = lm_config.inference_dep_q; - std::vector pcm(static_cast(frame_samples), 0.0f); - for (int32_t index = 0; index < frame_samples; ++index) { - pcm[static_cast(index)] = - 0.04f * static_cast((index % 97) - 48) / 48.0f; - } - std::vector input_codes(static_cast(public_n_q), -1); - std::vector output_codes(static_cast(public_n_q), -1); - std::vector output_pcm(static_cast(frame_samples), 0.0f); - int32_t text_token = -1; - bool produced = false; - personaplex::event::live_frame live{ - .payload = - { - .pcm = std::span{pcm}, - .input_codes_out = std::span{input_codes}, - .output_codes_out = std::span{output_codes}, - .text_token_out = text_token, - .produced_out = produced, - .pcm_out = std::span{output_pcm}, - }, - .error_out = err, - }; - REQUIRE(session.process_event(live)); - - personaplex::event::begin_flush begin_flush{.error_out = err}; - REQUIRE(session.process_event(begin_flush)); - std::fill(pcm.begin(), pcm.end(), 0.0f); - for (int32_t step = 0; step < 8 && !produced; ++step) { - personaplex::event::flush_frame flush{ - .payload = - { - .pcm = std::span{pcm}, - .input_codes_out = std::span{input_codes}, - .output_codes_out = std::span{output_codes}, - .text_token_out = text_token, - .produced_out = produced, - .pcm_out = std::span{output_pcm}, - }, - .error_out = err, - }; - REQUIRE(session.process_event(flush)); - } - REQUIRE(produced); - CHECK(std::any_of(output_pcm.begin(), output_pcm.end(), - [](const float sample) { return sample != 0.0f; })); - - personaplex::event::finish finish{.error_out = err}; - REQUIRE(session.process_event(finish)); - CHECK(session.is(sml::state)); -} - -TEST_CASE("PersonaPlex session rejects invalid injected dependencies") { - namespace personaplex = emel::speech::generator::moshi::personaplex::session; - namespace sml = stateforward::sml; - - auto model = std::make_unique(); - personaplex::dependencies dependencies{}; - personaplex::sm session{dependencies}; - emel::error::type err = emel::error::cast(personaplex::error::none); - personaplex::event::initialize initialize{ - .mimi_model = *model, - .lm_model = *model, - .voice_model = *model, - .sampling = - { - .enabled = true, - .consume_forced_text = true, - .audio_temperature = 0.8f, - .text_temperature = 0.7f, - .audio_top_k = 250, - .text_top_k = 25, - .seed = 1234, - }, - .max_blocks = 4, - .block_tokens = 4, - .error_out = err, - }; - - CHECK_FALSE(session.process_event(initialize)); - CHECK(err == emel::error::cast(personaplex::error::invalid_request)); - CHECK(session.is(sml::state)); -} - -TEST_CASE("PersonaPlex session models unexpected event ordering") { - namespace personaplex = emel::speech::generator::moshi::personaplex::session; - namespace sml = stateforward::sml; - - personaplex::dependencies dependencies{}; - personaplex::sm session{dependencies}; - emel::error::type err = emel::error::cast(personaplex::error::none); - personaplex::event::finish finish{.error_out = err}; - - CHECK_FALSE(session.process_event(finish)); - CHECK(err == emel::error::cast(personaplex::error::unexpected_event)); - CHECK(session.is(sml::state)); -} - -TEST_CASE("PersonaPlex session guards and effects expose failure routes") { - namespace personaplex = emel::speech::generator::moshi::personaplex::session; - - auto model = std::make_unique(); - personaplex::dependencies dependencies{}; - auto context = std::make_unique(dependencies); - emel::error::type err = emel::error::cast(personaplex::error::none); - personaplex::event::initialize initialize{ - .mimi_model = *model, - .lm_model = *model, - .voice_model = *model, - .error_out = err, - }; - personaplex::event::initialize_ctx initialize_ctx{}; - personaplex::event::initialize_run initialize_run{initialize, initialize_ctx}; - - CHECK(personaplex::guard::guard_encoder_initialize_failed{}(initialize_run, - *context)); - initialize_ctx.child_accepted = true; - initialize_ctx.frame_samples = 1920; - initialize_ctx.mimi_n_q = 8; - model->moshi_lm.inference_dep_q = 8; - CHECK(personaplex::guard::guard_encoder_initialize_succeeded{}(initialize_run, - *context)); - CHECK(personaplex::guard::guard_child_succeeded< - personaplex::event::initialize_run>{}(initialize_run, *context)); - CHECK_FALSE(personaplex::guard::guard_child_failed< - personaplex::event::initialize_run>{}(initialize_run, *context)); - personaplex::action::effect_fail_initialize_child< - personaplex::error::codec_initialize_failed>{}(initialize_run, *context); - CHECK(err == emel::error::cast(personaplex::error::codec_initialize_failed)); - - personaplex::event::advance_voice voice{.error_out = err}; - personaplex::event::phase_ctx voice_ctx{}; - personaplex::event::advance_voice_run voice_run{voice, voice_ctx}; - voice_ctx.child_accepted = true; - CHECK(personaplex::guard::guard_phase_succeeded_incomplete< - personaplex::event::advance_voice_run>{}(voice_run, *context)); - voice_ctx.complete = true; - CHECK(personaplex::guard::guard_phase_succeeded_complete< - personaplex::event::advance_voice_run>{}(voice_run, *context)); - voice_ctx.graph_err = 1; - CHECK(personaplex::guard::guard_phase_failed< - personaplex::event::advance_voice_run>{}(voice_run, *context)); - personaplex::action::effect_fail_advance_voice< - personaplex::error::voice_prefill_failed>{}(voice_run, *context); - CHECK(err == emel::error::cast(personaplex::error::voice_prefill_failed)); - - personaplex::event::advance_prompt prompt{ - .text_token = -1, - .error_out = err, - }; - personaplex::event::phase_ctx prompt_ctx{}; - personaplex::event::advance_prompt_run prompt_run{prompt, prompt_ctx}; - personaplex::action::effect_fail_advance_prompt< - personaplex::error::prompt_prefill_failed>{}(prompt_run, *context); - CHECK(err == emel::error::cast(personaplex::error::prompt_prefill_failed)); - - int32_t text_token = -1; - bool produced = true; - personaplex::event::live_frame live{ - .payload = - { - .text_token_out = text_token, - .produced_out = produced, - }, - .error_out = err, - }; - personaplex::event::frame_ctx frame_ctx{}; - personaplex::event::live_frame_run live_run{live, frame_ctx}; - CHECK(personaplex::guard::guard_frame_request_invalid< - personaplex::event::live_frame_run>{}(live_run, *context)); - frame_ctx.child_accepted = true; - frame_ctx.produced = true; - CHECK(personaplex::guard::guard_frame_generated_and_produced< - personaplex::event::live_frame_run>{}(live_run, *context)); - frame_ctx.produced = false; - CHECK(personaplex::guard::guard_frame_generated_without_output< - personaplex::event::live_frame_run>{}(live_run, *context)); - frame_ctx.child_err = 1; - CHECK(personaplex::guard::guard_frame_generate_failed< - personaplex::event::live_frame_run>{}(live_run, *context)); - personaplex::action::effect_fail_frame{}( - live_run, *context); - CHECK_FALSE(produced); - CHECK(err == emel::error::cast(personaplex::error::generate_failed)); - - personaplex::event::begin_flush begin_flush{.error_out = err}; - personaplex::event::simple_ctx begin_flush_ctx{}; - personaplex::event::begin_flush_run begin_flush_run{begin_flush, - begin_flush_ctx}; - personaplex::action::effect_fail_begin_flush_invalid{}(begin_flush_run, - *context); - CHECK(err == emel::error::cast(personaplex::error::invalid_request)); - - personaplex::event::finish finish{.error_out = err}; - personaplex::event::simple_ctx finish_ctx{}; - personaplex::event::finish_run finish_run{finish, finish_ctx}; - personaplex::action::effect_fail_finish_invalid{}(finish_run, *context); - CHECK(err == emel::error::cast(personaplex::error::invalid_request)); -} From c2dda9b628c53954f069ed580e653502af664b9e Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 17:42:26 -0500 Subject: [PATCH 13/61] refactor: move moshi runtime under speech predictor --- ...r_moshi.mmd => speech_predictor_moshi.mmd} | 0 ...md => speech_predictor_moshi_executor.mmd} | 0 ...tor_moshi.md => speech_predictor_moshi.md} | 388 ++++++------ ....md => speech_predictor_moshi_executor.md} | 574 +++++++++--------- CMakeLists.txt | 4 +- README.md | 4 +- src/emel/speech/generator/moshi/any.hpp | 9 - .../moshi/actions.hpp | 10 +- src/emel/speech/predictor/moshi/any.hpp | 9 + .../moshi/context.hpp | 6 +- .../{generator => predictor}/moshi/detail.hpp | 6 +- .../{generator => predictor}/moshi/errors.hpp | 4 +- .../{generator => predictor}/moshi/events.hpp | 14 +- .../moshi/executor/actions.hpp | 10 +- .../moshi/executor/any.hpp | 12 +- .../moshi/executor/context.hpp | 6 +- .../moshi/executor/detail.hpp | 4 +- .../moshi/executor/errors.hpp | 4 +- .../moshi/executor/events.hpp | 20 +- .../moshi/executor/guards.hpp | 10 +- .../moshi/executor/sm.hpp | 14 +- .../{generator => predictor}/moshi/guards.hpp | 10 +- .../{generator => predictor}/moshi/sm.hpp | 12 +- .../moshi_executor_streaming_tests.cpp | 10 +- .../moshi_fixture.hpp | 4 +- .../moshi_lifecycle_tests.cpp | 24 +- .../bench/speech/personaplex_emel_runner.cpp | 8 +- 27 files changed, 588 insertions(+), 588 deletions(-) rename .planning/architecture/mermaid/{speech_generator_moshi.mmd => speech_predictor_moshi.mmd} (100%) rename .planning/architecture/mermaid/{speech_generator_moshi_executor.mmd => speech_predictor_moshi_executor.mmd} (100%) rename .planning/architecture/{speech_generator_moshi.md => speech_predictor_moshi.md} (59%) rename .planning/architecture/{speech_generator_moshi_executor.md => speech_predictor_moshi_executor.md} (60%) delete mode 100644 src/emel/speech/generator/moshi/any.hpp rename src/emel/speech/{generator => predictor}/moshi/actions.hpp (99%) create mode 100644 src/emel/speech/predictor/moshi/any.hpp rename src/emel/speech/{generator => predictor}/moshi/context.hpp (94%) rename src/emel/speech/{generator => predictor}/moshi/detail.hpp (86%) rename src/emel/speech/{generator => predictor}/moshi/errors.hpp (80%) rename src/emel/speech/{generator => predictor}/moshi/events.hpp (96%) rename src/emel/speech/{generator => predictor}/moshi/executor/actions.hpp (99%) rename src/emel/speech/{generator => predictor}/moshi/executor/any.hpp (79%) rename src/emel/speech/{generator => predictor}/moshi/executor/context.hpp (94%) rename src/emel/speech/{generator => predictor}/moshi/executor/detail.hpp (99%) rename src/emel/speech/{generator => predictor}/moshi/executor/errors.hpp (69%) rename src/emel/speech/{generator => predictor}/moshi/executor/events.hpp (90%) rename src/emel/speech/{generator => predictor}/moshi/executor/guards.hpp (99%) rename src/emel/speech/{generator => predictor}/moshi/executor/sm.hpp (99%) rename src/emel/speech/{generator => predictor}/moshi/guards.hpp (99%) rename src/emel/speech/{generator => predictor}/moshi/sm.hpp (99%) rename tests/speech/{generator => predictor}/moshi_executor_streaming_tests.cpp (94%) rename tests/speech/{generator => predictor}/moshi_fixture.hpp (98%) rename tests/speech/{generator => predictor}/moshi_lifecycle_tests.cpp (99%) diff --git a/.planning/architecture/mermaid/speech_generator_moshi.mmd b/.planning/architecture/mermaid/speech_predictor_moshi.mmd similarity index 100% rename from .planning/architecture/mermaid/speech_generator_moshi.mmd rename to .planning/architecture/mermaid/speech_predictor_moshi.mmd diff --git a/.planning/architecture/mermaid/speech_generator_moshi_executor.mmd b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd similarity index 100% rename from .planning/architecture/mermaid/speech_generator_moshi_executor.mmd rename to .planning/architecture/mermaid/speech_predictor_moshi_executor.mmd diff --git a/.planning/architecture/speech_generator_moshi.md b/.planning/architecture/speech_predictor_moshi.md similarity index 59% rename from .planning/architecture/speech_generator_moshi.md rename to .planning/architecture/speech_predictor_moshi.md index 04a1778b..5e943db6 100644 --- a/.planning/architecture/speech_generator_moshi.md +++ b/.planning/architecture/speech_predictor_moshi.md @@ -1,6 +1,6 @@ -# speech_generator_moshi +# speech_predictor_moshi -Source: [`emel/speech/generator/moshi/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) +Source: [`emel/speech/predictor/moshi/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) ## Mermaid @@ -206,195 +206,195 @@ stateDiagram-v2 | Source | Event | Guard | Action | Target | | --- | --- | --- | --- | --- | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_configure_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_configure_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_reserve_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_voice_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_load_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_voice_prefill_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_capture_voice_prefill_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_begin_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_loaded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_embedding_frame_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_run_voice_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_copy_voice_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_voice_prefill_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_nonempty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_empty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_bind_empty_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_personaplex_prompt_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_capture_personaplex_prompt_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_begin_personaplex_prompt_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_pre_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_text_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_personaplex_prompt_text_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_post_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_phase_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_and_build_personaplex_prompt_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_run_personaplex_prompt_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_finish_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_step_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_allocate_step_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_step_blocked_by_voice_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_voice_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_step_request_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_step_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_capture_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_begin_step>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_no_input_write>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_build_input_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_run_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_replace_depformer_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_replace_audio_with_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_use_graph_audio_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_apply_delay_mask_and_advance>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_should_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_provided_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_write_generated_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_skip_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_consume_skip>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_before_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_past_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_collect_delayed_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_output_has_ungenerated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_output_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_publish_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_has_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_store_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_no_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_step_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`reset_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_configure_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_configure_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_reserve_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_voice_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_load_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_voice_prefill_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_capture_voice_prefill_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_begin_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_loaded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_run_voice_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_copy_voice_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_nonempty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_empty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_empty_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_personaplex_prompt_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_capture_personaplex_prompt_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_begin_personaplex_prompt_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_pre_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_text_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_personaplex_prompt_text_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_post_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_phase_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_and_build_personaplex_prompt_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_run_personaplex_prompt_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_finish_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_step_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_step_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_step_blocked_by_voice_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_voice_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_step_request_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_step_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_capture_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_begin_step>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_no_input_write>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_input_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_run_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_replace_depformer_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_replace_audio_with_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_use_graph_audio_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_apply_delay_mask_and_advance>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_should_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_provided_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_generated_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_skip_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_consume_skip>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_before_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_past_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_collect_delayed_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_output_has_ungenerated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_output_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_step_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`reset_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | diff --git a/.planning/architecture/speech_generator_moshi_executor.md b/.planning/architecture/speech_predictor_moshi_executor.md similarity index 60% rename from .planning/architecture/speech_generator_moshi_executor.md rename to .planning/architecture/speech_predictor_moshi_executor.md index b38ef744..fe38a8ef 100644 --- a/.planning/architecture/speech_generator_moshi_executor.md +++ b/.planning/architecture/speech_predictor_moshi_executor.md @@ -1,6 +1,6 @@ -# speech_generator_moshi_executor +# speech_predictor_moshi_executor -Source: [`emel/speech/generator/moshi/executor/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) +Source: [`emel/speech/predictor/moshi/executor/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) ## Mermaid @@ -299,288 +299,288 @@ stateDiagram-v2 | Source | Event | Guard | Action | Target | | --- | --- | --- | --- | --- | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_sampling_seed_nonzero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_nonzero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_sampling_seed_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_zero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_requested_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_exceeds_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_full_card_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_audio_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_requested_audio_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_audio_sampling_top_k_exceeds_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_full_card_audio_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_has_initialize_done_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_no_initialize_done_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_has_initialize_error_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_no_initialize_error_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_model_matches>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_model_mismatch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_model_mismatch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_shape_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_step_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_request_shape>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_begin_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_external_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_external_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_token_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_input_text_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_token_input_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_input_text_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_text_embedding_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_text_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_text_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_text_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_input_audio_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_skip_zero_input_audio_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_input_audio_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_audio_embedding_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_audio_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_input_audio_codebooks>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_input_audio_codebook>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_audio_codebooks_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_finish_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_input_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_binding_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_kv>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_binding_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_kv_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_temporal_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_position_advance_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_position_advance_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_rope<0>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_copy_temporal_layer_rope<0>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_rope<1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_copy_temporal_layer_rope<1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_write_temporal_layer_kv_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_attention>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_temporal_layer_attention_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm2_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm2_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_silu_gate_silu>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_silu_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_silu_gate_mul>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_silu_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_temporal_layer_ff_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_ff_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_ff_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_temporal_layers>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_temporal_layer>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layers_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_out_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_temporal_out_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_temporal_out_norm>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_and_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_without_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_sampling_config_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_sampling>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_scale_text_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_text_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_sampled_text_token_ready>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_sampled_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_forced_text_sampling_consumed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_sampling_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_text_logits_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_binding_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_kv>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_binding_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_reset_depformer_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_kv_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_reset_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_reset_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_advance_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_position_advance_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_use_depformer_scheduled_weight>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_use_depformer_codebook_weight>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_text_input_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_text_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_audio_input_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_audio_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_text_input_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_text_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_audio_input_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_audio_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_depformer_input_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_input_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_write_depformer_layer_kv_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_attention>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_depformer_layer_attention_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm2_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm2_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_silu_gate_silu>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_silu_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_silu_gate_mul>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_silu_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_apply_depformer_layer_ff_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_ff_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_ff_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_depformer_layers>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_layer>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_bind_depformer_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_sampling>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_depformer_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_scale_depformer_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_select_depformer_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_logits_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_sampling_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_publish_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_sampling_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_more_depformer_codebooks>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_codebook>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_depformer_codebooks_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_depformer_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_advance_depformer_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_not_initialized>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/moshi/executor/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_nonzero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_nonzero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_zero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_requested_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_exceeds_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_full_card_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_audio_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_requested_audio_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_audio_sampling_top_k_exceeds_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_full_card_audio_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_has_initialize_done_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_no_initialize_done_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_has_initialize_error_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_no_initialize_error_callback>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_step_model_matches>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_model_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_step_model_mismatch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_model_mismatch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_step_shape_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_shape_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_step_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_request_shape>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_begin_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_execution_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_external_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_external_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_token_input_embedding_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_input_text_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_text_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_token_input_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_text_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_input_text_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_text_embedding_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_text_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_text_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_text_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_input_audio_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_skip_zero_input_audio_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_current_input_audio_token_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_input_audio_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_audio_embedding_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_audio_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_more_input_audio_codebooks>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_advance_input_audio_codebook>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_audio_token_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_audio_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_audio_codebooks_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_finish_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_input_embedding_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_kv_binding_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_kv>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_kv_binding_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_kv_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_bind_temporal_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_kv_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_advance_temporal_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_position_advance_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_position_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_position_advance_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_position_valid_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_rope<0>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_copy_temporal_layer_rope<0>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_rope<1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_copy_temporal_layer_rope<1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_rope_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_write_temporal_layer_kv_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_key_rope_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_cache_write_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_attention>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_attention_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_out_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_temporal_layer_attention_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm2_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm2_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm2_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_in_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_silu_gate_silu>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_silu_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_silu_gate_mul>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_silu_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_silu_gate_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_gating_out_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_temporal_layer_ff_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_ff_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_ff_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_more_temporal_layers>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_advance_temporal_layer>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layers_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_out_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_out_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_temporal_out_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_temporal_out_norm>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_and_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_without_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_forced_text_sampling_config_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_sampling>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_scale_text_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_text_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampled_text_token_ready>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_sampled_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_forced_text_sampling_consumed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_sampling_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_kv_binding_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_kv>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_kv_binding_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_kv_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_depformer_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_bind_depformer_kv`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_kv_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_kv_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_position_reset_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_advance_depformer_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_position_reset_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_position_reset_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_position_advance_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_position_advance_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_use_depformer_scheduled_weight>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_use_depformer_codebook_weight>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_weight_route_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_scheduled_weight_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_text_input_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_text_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_audio_input_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_audio_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_weight_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_input_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_input_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_text_input_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_text_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_audio_input_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_audio_input_embedding>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_input_projection_embedding_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_bind`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_embedding_row_fetch>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_row`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_row_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_depformer_input_embedding_row>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_row_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_embedding_row_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_input_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_embedding_apply`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_input_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_input_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_write_depformer_layer_kv_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_cache_write_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_attention>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_cache_write_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_attention_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_attention_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_out_projection>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_out_projection_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_out_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_depformer_layer_attention_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm2_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_rms_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm2_scale>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm2_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_norm2_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_gating_in>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_in_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_silu_gate_silu>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_in_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_silu_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_silu_gate_mul>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_silu_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_silu_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_mul`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_silu_gate_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_silu_gate_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bound>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_gating_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_gating_out_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_gating_out_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_apply_depformer_layer_ff_residual>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_ff_residual_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_ff_residual_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_more_depformer_layers>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_advance_depformer_layer>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_ff_residual_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_sampling>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_depformer_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_scale_depformer_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_depformer_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_sampling_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_sampling_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_more_depformer_codebooks>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_advance_depformer_codebook>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_codebooks_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_codebook_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_advance_depformer_position>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_position_advance_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_not_initialized>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | diff --git a/CMakeLists.txt b/CMakeLists.txt index db328e45..2750ec7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,8 +189,8 @@ if(EMEL_ENABLE_TESTS) tests/speech/codec/mimi_detail_tests.cpp tests/speech/codec/mimi_lifecycle_tests.cpp tests/speech/generator/lifecycle_tests.cpp - tests/speech/generator/moshi_lifecycle_tests.cpp - tests/speech/generator/moshi_executor_streaming_tests.cpp + tests/speech/predictor/moshi_lifecycle_tests.cpp + tests/speech/predictor/moshi_executor_streaming_tests.cpp tests/speech/encoder/whisper/lifecycle_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp diff --git a/README.md b/README.md index 08eb17d6..f701290b 100644 --- a/README.md +++ b/README.md @@ -183,9 +183,9 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/speech_codec_mimi.md`](.planning/architecture/speech_codec_mimi.md) - [`.planning/architecture/speech_decoder_whisper.md`](.planning/architecture/speech_decoder_whisper.md) - [`.planning/architecture/speech_encoder_whisper.md`](.planning/architecture/speech_encoder_whisper.md) -- [`.planning/architecture/speech_generator_moshi_executor.md`](.planning/architecture/speech_generator_moshi_executor.md) -- [`.planning/architecture/speech_generator_moshi.md`](.planning/architecture/speech_generator_moshi.md) - [`.planning/architecture/speech_generator.md`](.planning/architecture/speech_generator.md) +- [`.planning/architecture/speech_predictor_moshi_executor.md`](.planning/architecture/speech_predictor_moshi_executor.md) +- [`.planning/architecture/speech_predictor_moshi.md`](.planning/architecture/speech_predictor_moshi.md) - [`.planning/architecture/speech_tokenizer_moshi.md`](.planning/architecture/speech_tokenizer_moshi.md) - [`.planning/architecture/tensor_view.md`](.planning/architecture/tensor_view.md) - [`.planning/architecture/text_conditioner.md`](.planning/architecture/text_conditioner.md) diff --git a/src/emel/speech/generator/moshi/any.hpp b/src/emel/speech/generator/moshi/any.hpp deleted file mode 100644 index 67fa0047..00000000 --- a/src/emel/speech/generator/moshi/any.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "emel/speech/generator/moshi/sm.hpp" - -namespace emel::speech::generator::moshi { - -using MoshiGenerator = sm; - -} // namespace emel::speech::generator::moshi diff --git a/src/emel/speech/generator/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp similarity index 99% rename from src/emel/speech/generator/moshi/actions.hpp rename to src/emel/speech/predictor/moshi/actions.hpp index fb4a7d59..5ed4d981 100644 --- a/src/emel/speech/generator/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -8,11 +8,11 @@ #include "emel/kernel/detail.hpp" #include "emel/memory/events.hpp" #include "emel/model/moshi/detail.hpp" -#include "emel/speech/generator/moshi/context.hpp" -#include "emel/speech/generator/moshi/detail.hpp" -#include "emel/speech/generator/moshi/events.hpp" +#include "emel/speech/predictor/moshi/context.hpp" +#include "emel/speech/predictor/moshi/detail.hpp" +#include "emel/speech/predictor/moshi/events.hpp" -namespace emel::speech::generator::moshi::action { +namespace emel::speech::predictor::moshi::action { namespace detail_ns { @@ -949,4 +949,4 @@ struct effect_mark_unexpected_and_store { } }; -} // namespace emel::speech::generator::moshi::action +} // namespace emel::speech::predictor::moshi::action diff --git a/src/emel/speech/predictor/moshi/any.hpp b/src/emel/speech/predictor/moshi/any.hpp new file mode 100644 index 00000000..53c2d48f --- /dev/null +++ b/src/emel/speech/predictor/moshi/any.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "emel/speech/predictor/moshi/sm.hpp" + +namespace emel::speech::predictor::moshi { + +using MoshiGenerator = sm; + +} // namespace emel::speech::predictor::moshi diff --git a/src/emel/speech/generator/moshi/context.hpp b/src/emel/speech/predictor/moshi/context.hpp similarity index 94% rename from src/emel/speech/generator/moshi/context.hpp rename to src/emel/speech/predictor/moshi/context.hpp index 42409341..3daefbd6 100644 --- a/src/emel/speech/generator/moshi/context.hpp +++ b/src/emel/speech/predictor/moshi/context.hpp @@ -7,9 +7,9 @@ #include "emel/memory/hybrid/sm.hpp" #include "emel/model/data.hpp" #include "emel/model/moshi/detail.hpp" -#include "emel/speech/generator/moshi/events.hpp" +#include "emel/speech/predictor/moshi/events.hpp" -namespace emel::speech::generator::moshi::action { +namespace emel::speech::predictor::moshi::action { inline constexpr int32_t k_max_codebooks = static_cast(event::k_max_codebooks); @@ -87,4 +87,4 @@ bind_graph_executor(void *executor, return graph_binding{.executor = executor, .dispatch_step = &dispatch_step}; } -} // namespace emel::speech::generator::moshi::action +} // namespace emel::speech::predictor::moshi::action diff --git a/src/emel/speech/generator/moshi/detail.hpp b/src/emel/speech/predictor/moshi/detail.hpp similarity index 86% rename from src/emel/speech/generator/moshi/detail.hpp rename to src/emel/speech/predictor/moshi/detail.hpp index 29acbcb8..c7f0b30d 100644 --- a/src/emel/speech/generator/moshi/detail.hpp +++ b/src/emel/speech/predictor/moshi/detail.hpp @@ -2,9 +2,9 @@ #include -#include "emel/speech/generator/moshi/context.hpp" +#include "emel/speech/predictor/moshi/context.hpp" -namespace emel::speech::generator::moshi::detail { +namespace emel::speech::predictor::moshi::detail { template constexpr decltype(auto) @@ -35,4 +35,4 @@ inline int32_t cache_at(const action::lmgen_state &lmgen, const int32_t row, .cache[static_cast(row * action::k_max_codebooks + column)]; } -} // namespace emel::speech::generator::moshi::detail +} // namespace emel::speech::predictor::moshi::detail diff --git a/src/emel/speech/generator/moshi/errors.hpp b/src/emel/speech/predictor/moshi/errors.hpp similarity index 80% rename from src/emel/speech/generator/moshi/errors.hpp rename to src/emel/speech/predictor/moshi/errors.hpp index 1a4fcb3b..0db3677a 100644 --- a/src/emel/speech/generator/moshi/errors.hpp +++ b/src/emel/speech/predictor/moshi/errors.hpp @@ -2,7 +2,7 @@ #include "emel/error/error.hpp" -namespace emel::speech::generator::moshi { +namespace emel::speech::predictor::moshi { enum class error : emel::error::type { none = 0, @@ -19,4 +19,4 @@ enum class error : emel::error::type { unexpected_event = 11, }; -} // namespace emel::speech::generator::moshi +} // namespace emel::speech::predictor::moshi diff --git a/src/emel/speech/generator/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp similarity index 96% rename from src/emel/speech/generator/moshi/events.hpp rename to src/emel/speech/predictor/moshi/events.hpp index 8b9ea92e..8de23247 100644 --- a/src/emel/speech/generator/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -9,9 +9,9 @@ #include "emel/error/error.hpp" #include "emel/memory/view.hpp" #include "emel/model/data.hpp" -#include "emel/speech/generator/moshi/errors.hpp" +#include "emel/speech/predictor/moshi/errors.hpp" -namespace emel::speech::generator::moshi::events { +namespace emel::speech::predictor::moshi::events { struct initialize_done; struct initialize_error; @@ -26,9 +26,9 @@ struct prefill_personaplex_prompt_error; struct step_done; struct step_error; -} // namespace emel::speech::generator::moshi::events +} // namespace emel::speech::predictor::moshi::events -namespace emel::speech::generator::moshi::event { +namespace emel::speech::predictor::moshi::event { inline constexpr std::size_t k_max_codebooks = 64; inline constexpr std::size_t k_max_voice_embedding_dim = 8192; @@ -241,9 +241,9 @@ struct reset_run { const reset &request; }; -} // namespace emel::speech::generator::moshi::event +} // namespace emel::speech::predictor::moshi::event -namespace emel::speech::generator::moshi::events { +namespace emel::speech::predictor::moshi::events { struct initialize_done { const event::initialize *request = nullptr; @@ -308,4 +308,4 @@ struct step_error { emel::error::type err = emel::error::cast(error::none); }; -} // namespace emel::speech::generator::moshi::events +} // namespace emel::speech::predictor::moshi::events diff --git a/src/emel/speech/generator/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp similarity index 99% rename from src/emel/speech/generator/moshi/executor/actions.hpp rename to src/emel/speech/predictor/moshi/executor/actions.hpp index 4abe4ae7..1e8eacb3 100644 --- a/src/emel/speech/generator/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -1,16 +1,16 @@ #pragma once #include "emel/model/moshi/detail.hpp" -#include "emel/speech/generator/moshi/executor/context.hpp" -#include "emel/speech/generator/moshi/executor/detail.hpp" -#include "emel/speech/generator/moshi/executor/events.hpp" +#include "emel/speech/predictor/moshi/executor/context.hpp" +#include "emel/speech/predictor/moshi/executor/detail.hpp" +#include "emel/speech/predictor/moshi/executor/events.hpp" #include #include #include #include -namespace emel::speech::generator::moshi::executor::action { +namespace emel::speech::predictor::moshi::executor::action { namespace detail_ns { @@ -1905,4 +1905,4 @@ struct effect_mark_unexpected_and_store { } }; -} // namespace emel::speech::generator::moshi::executor::action +} // namespace emel::speech::predictor::moshi::executor::action diff --git a/src/emel/speech/generator/moshi/executor/any.hpp b/src/emel/speech/predictor/moshi/executor/any.hpp similarity index 79% rename from src/emel/speech/generator/moshi/executor/any.hpp rename to src/emel/speech/predictor/moshi/executor/any.hpp index 37959433..7f713a19 100644 --- a/src/emel/speech/generator/moshi/executor/any.hpp +++ b/src/emel/speech/predictor/moshi/executor/any.hpp @@ -1,18 +1,18 @@ #pragma once -#include "emel/speech/generator/moshi/executor/sm.hpp" +#include "emel/speech/predictor/moshi/executor/sm.hpp" -namespace emel::speech::generator::moshi::executor { +namespace emel::speech::predictor::moshi::executor { inline bool dispatch_graph_step( void *executor_ptr, - const emel::speech::generator::moshi::event::graph_step &ev) noexcept { + const emel::speech::predictor::moshi::event::graph_step &ev) noexcept { return static_cast(executor_ptr)->process_event(ev); } -inline emel::speech::generator::moshi::action::graph_binding +inline emel::speech::predictor::moshi::action::graph_binding bind_graph_executor(sm &executor) noexcept { - return emel::speech::generator::moshi::action::bind_graph_executor( + return emel::speech::predictor::moshi::action::bind_graph_executor( &executor, dispatch_graph_step); } @@ -49,4 +49,4 @@ bind_kv_caches(const temporal_kv_binding &temporal, using MoshiExecutor = sm; -} // namespace emel::speech::generator::moshi::executor +} // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/generator/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp similarity index 94% rename from src/emel/speech/generator/moshi/executor/context.hpp rename to src/emel/speech/predictor/moshi/executor/context.hpp index 3743d3a6..c5aecd96 100644 --- a/src/emel/speech/generator/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -7,9 +7,9 @@ #include "emel/memory/view.hpp" #include "emel/model/data.hpp" #include "emel/model/moshi/detail.hpp" -#include "emel/speech/generator/moshi/executor/detail.hpp" +#include "emel/speech/predictor/moshi/executor/detail.hpp" -namespace emel::speech::generator::moshi::executor::action { +namespace emel::speech::predictor::moshi::executor::action { using temporal_kv_bind_fn = bool(void *, const emel::model::data &, const emel::memory::view::snapshot &, int32_t, @@ -104,4 +104,4 @@ bind_kv_caches(const temporal_kv_binding &temporal, }; } -} // namespace emel::speech::generator::moshi::executor::action +} // namespace emel::speech::predictor::moshi::executor::action diff --git a/src/emel/speech/generator/moshi/executor/detail.hpp b/src/emel/speech/predictor/moshi/executor/detail.hpp similarity index 99% rename from src/emel/speech/generator/moshi/executor/detail.hpp rename to src/emel/speech/predictor/moshi/executor/detail.hpp index 128794fd..10b77aa9 100644 --- a/src/emel/speech/generator/moshi/executor/detail.hpp +++ b/src/emel/speech/predictor/moshi/executor/detail.hpp @@ -14,7 +14,7 @@ #include "emel/memory/view.hpp" #include "emel/model/data.hpp" -namespace emel::speech::generator::moshi::executor::detail { +namespace emel::speech::predictor::moshi::executor::detail { using dtype = emel::kernel::event::dtype; using tensor_record = emel::model::data::tensor_record; @@ -342,4 +342,4 @@ inline void compute_sampling_exponential_argmax( } } -} // namespace emel::speech::generator::moshi::executor::detail +} // namespace emel::speech::predictor::moshi::executor::detail diff --git a/src/emel/speech/generator/moshi/executor/errors.hpp b/src/emel/speech/predictor/moshi/executor/errors.hpp similarity index 69% rename from src/emel/speech/generator/moshi/executor/errors.hpp rename to src/emel/speech/predictor/moshi/executor/errors.hpp index b932f880..57eee8a4 100644 --- a/src/emel/speech/generator/moshi/executor/errors.hpp +++ b/src/emel/speech/predictor/moshi/executor/errors.hpp @@ -2,7 +2,7 @@ #include "emel/error/error.hpp" -namespace emel::speech::generator::moshi::executor { +namespace emel::speech::predictor::moshi::executor { enum class error : emel::error::type { none = 0, @@ -14,4 +14,4 @@ enum class error : emel::error::type { unexpected_event = 6, }; -} // namespace emel::speech::generator::moshi::executor +} // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/generator/moshi/executor/events.hpp b/src/emel/speech/predictor/moshi/executor/events.hpp similarity index 90% rename from src/emel/speech/generator/moshi/executor/events.hpp rename to src/emel/speech/predictor/moshi/executor/events.hpp index c70b3ccd..7915280a 100644 --- a/src/emel/speech/generator/moshi/executor/events.hpp +++ b/src/emel/speech/predictor/moshi/executor/events.hpp @@ -6,18 +6,18 @@ #include "emel/error/error.hpp" #include "emel/memory/streaming/events.hpp" #include "emel/model/data.hpp" -#include "emel/speech/generator/moshi/events.hpp" -#include "emel/speech/generator/moshi/executor/detail.hpp" -#include "emel/speech/generator/moshi/executor/errors.hpp" +#include "emel/speech/predictor/moshi/events.hpp" +#include "emel/speech/predictor/moshi/executor/detail.hpp" +#include "emel/speech/predictor/moshi/executor/errors.hpp" -namespace emel::speech::generator::moshi::executor::events { +namespace emel::speech::predictor::moshi::executor::events { struct initialize_done; struct initialize_error; -} // namespace emel::speech::generator::moshi::executor::events +} // namespace emel::speech::predictor::moshi::executor::events -namespace emel::speech::generator::moshi::executor::event { +namespace emel::speech::predictor::moshi::executor::event { struct initialize { explicit initialize(const emel::model::data &model_ref) noexcept @@ -140,15 +140,15 @@ struct initialize_run { }; struct step_run { - const emel::speech::generator::moshi::event::graph_step &request; + const emel::speech::predictor::moshi::event::graph_step &request; step_ctx &ctx; }; struct reset {}; -} // namespace emel::speech::generator::moshi::executor::event +} // namespace emel::speech::predictor::moshi::executor::event -namespace emel::speech::generator::moshi::executor::events { +namespace emel::speech::predictor::moshi::executor::events { struct initialize_done { const event::initialize *request = nullptr; @@ -161,4 +161,4 @@ struct initialize_error { emel::error::type err = emel::error::cast(error::none); }; -} // namespace emel::speech::generator::moshi::executor::events +} // namespace emel::speech::predictor::moshi::executor::events diff --git a/src/emel/speech/generator/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp similarity index 99% rename from src/emel/speech/generator/moshi/executor/guards.hpp rename to src/emel/speech/predictor/moshi/executor/guards.hpp index da0b4def..e2b7e850 100644 --- a/src/emel/speech/generator/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -4,11 +4,11 @@ #include "emel/model/loader/errors.hpp" #include "emel/model/moshi/detail.hpp" -#include "emel/speech/generator/moshi/executor/context.hpp" -#include "emel/speech/generator/moshi/executor/detail.hpp" -#include "emel/speech/generator/moshi/executor/events.hpp" +#include "emel/speech/predictor/moshi/executor/context.hpp" +#include "emel/speech/predictor/moshi/executor/detail.hpp" +#include "emel/speech/predictor/moshi/executor/events.hpp" -namespace emel::speech::generator::moshi::executor::guard { +namespace emel::speech::predictor::moshi::executor::guard { struct guard_bind_contract_valid { bool operator()(const event::initialize_run &runtime_ev, @@ -2091,4 +2091,4 @@ struct guard_unexpected_error_out_absent { } }; -} // namespace emel::speech::generator::moshi::executor::guard +} // namespace emel::speech::predictor::moshi::executor::guard diff --git a/src/emel/speech/generator/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp similarity index 99% rename from src/emel/speech/generator/moshi/executor/sm.hpp rename to src/emel/speech/predictor/moshi/executor/sm.hpp index cee02fbb..11583a0f 100644 --- a/src/emel/speech/generator/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -4,12 +4,12 @@ #include #include "emel/sm.hpp" -#include "emel/speech/generator/moshi/executor/actions.hpp" -#include "emel/speech/generator/moshi/executor/context.hpp" -#include "emel/speech/generator/moshi/executor/events.hpp" -#include "emel/speech/generator/moshi/executor/guards.hpp" +#include "emel/speech/predictor/moshi/executor/actions.hpp" +#include "emel/speech/predictor/moshi/executor/context.hpp" +#include "emel/speech/predictor/moshi/executor/events.hpp" +#include "emel/speech/predictor/moshi/executor/guards.hpp" -namespace emel::speech::generator::moshi::executor { +namespace emel::speech::predictor::moshi::executor { struct state_uninitialized {}; struct state_bind_contract_decision {}; @@ -1017,7 +1017,7 @@ struct sm : public emel::sm { } bool - process_event(const emel::speech::generator::moshi::event::graph_step &ev) { + process_event(const emel::speech::predictor::moshi::event::graph_step &ev) { event::step_ctx ctx{}; event::step_run runtime_ev{ev, ctx}; const bool accepted = base_type::process_event(runtime_ev); @@ -1031,4 +1031,4 @@ struct sm : public emel::sm { using Executor = sm; -} // namespace emel::speech::generator::moshi::executor +} // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/generator/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp similarity index 99% rename from src/emel/speech/generator/moshi/guards.hpp rename to src/emel/speech/predictor/moshi/guards.hpp index 3aa3b764..46d2da8e 100644 --- a/src/emel/speech/generator/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -4,11 +4,11 @@ #include "emel/memory/hybrid/errors.hpp" #include "emel/model/loader/errors.hpp" #include "emel/model/moshi/detail.hpp" -#include "emel/speech/generator/moshi/context.hpp" -#include "emel/speech/generator/moshi/detail.hpp" -#include "emel/speech/generator/moshi/events.hpp" +#include "emel/speech/predictor/moshi/context.hpp" +#include "emel/speech/predictor/moshi/detail.hpp" +#include "emel/speech/predictor/moshi/events.hpp" -namespace emel::speech::generator::moshi::guard { +namespace emel::speech::predictor::moshi::guard { struct guard_bind_contract_valid { bool operator()(const event::initialize_run &runtime_ev, @@ -683,4 +683,4 @@ struct guard_unexpected_error_out_absent { } }; -} // namespace emel::speech::generator::moshi::guard +} // namespace emel::speech::predictor::moshi::guard diff --git a/src/emel/speech/generator/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp similarity index 99% rename from src/emel/speech/generator/moshi/sm.hpp rename to src/emel/speech/predictor/moshi/sm.hpp index 3c2cf690..5d2824b6 100644 --- a/src/emel/speech/generator/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -6,12 +6,12 @@ #include #include "emel/sm.hpp" -#include "emel/speech/generator/moshi/actions.hpp" -#include "emel/speech/generator/moshi/context.hpp" -#include "emel/speech/generator/moshi/events.hpp" -#include "emel/speech/generator/moshi/guards.hpp" +#include "emel/speech/predictor/moshi/actions.hpp" +#include "emel/speech/predictor/moshi/context.hpp" +#include "emel/speech/predictor/moshi/events.hpp" +#include "emel/speech/predictor/moshi/guards.hpp" -namespace emel::speech::generator::moshi { +namespace emel::speech::predictor::moshi { struct state_uninitialized {}; struct state_bind_contract_decision {}; @@ -739,4 +739,4 @@ struct sm : public emel::sm { using Generator = sm; -} // namespace emel::speech::generator::moshi +} // namespace emel::speech::predictor::moshi diff --git a/tests/speech/generator/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp similarity index 94% rename from tests/speech/generator/moshi_executor_streaming_tests.cpp rename to tests/speech/predictor/moshi_executor_streaming_tests.cpp index 36953bc8..ec07b963 100644 --- a/tests/speech/generator/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -8,16 +8,16 @@ #include "emel/error/error.hpp" #include "emel/memory/streaming/sm.hpp" -#include "emel/speech/generator/moshi/any.hpp" -#include "emel/speech/generator/moshi/executor/any.hpp" +#include "emel/speech/predictor/moshi/any.hpp" +#include "emel/speech/predictor/moshi/executor/any.hpp" #include "moshi_fixture.hpp" namespace { namespace memory_streaming = emel::memory::streaming; -namespace moshi = emel::speech::generator::moshi; -namespace executor = emel::speech::generator::moshi::executor; -using emel::speech::generator::moshi::test::load_fixture_or_skip; +namespace moshi = emel::speech::predictor::moshi; +namespace executor = emel::speech::predictor::moshi::executor; +using emel::speech::predictor::moshi::test::load_fixture_or_skip; struct cache_storage { cache_storage(const int32_t layer_count, const int32_t capacity, diff --git a/tests/speech/generator/moshi_fixture.hpp b/tests/speech/predictor/moshi_fixture.hpp similarity index 98% rename from tests/speech/generator/moshi_fixture.hpp rename to tests/speech/predictor/moshi_fixture.hpp index fce5eb4c..492c5f6c 100644 --- a/tests/speech/generator/moshi_fixture.hpp +++ b/tests/speech/predictor/moshi_fixture.hpp @@ -17,7 +17,7 @@ #include "emel/gguf/loader/sm.hpp" #include "emel/model/detail.hpp" -namespace emel::speech::generator::moshi::test { +namespace emel::speech::predictor::moshi::test { struct loaded_fixture { std::vector file_bytes = {}; @@ -133,4 +133,4 @@ inline loaded_fixture load_fixture_or_skip(const std::string_view name) { return loaded; } -} // namespace emel::speech::generator::moshi::test +} // namespace emel::speech::predictor::moshi::test diff --git a/tests/speech/generator/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp similarity index 99% rename from tests/speech/generator/moshi_lifecycle_tests.cpp rename to tests/speech/predictor/moshi_lifecycle_tests.cpp index d674bac5..2d7ae32f 100644 --- a/tests/speech/generator/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -14,20 +14,20 @@ #include "emel/memory/streaming/sm.hpp" #include "emel/model/moshi/detail.hpp" #include "emel/speech/codec/mimi/any.hpp" -#include "emel/speech/generator/moshi/any.hpp" -#include "emel/speech/generator/moshi/executor/any.hpp" +#include "emel/speech/predictor/moshi/any.hpp" +#include "emel/speech/predictor/moshi/executor/any.hpp" #include "moshi_fixture.hpp" namespace { -namespace moshi = emel::speech::generator::moshi; -namespace moshi_executor = emel::speech::generator::moshi::executor; +namespace moshi = emel::speech::predictor::moshi; +namespace moshi_executor = emel::speech::predictor::moshi::executor; namespace memory_streaming = emel::memory::streaming; namespace mimi = emel::speech::codec::mimi; namespace model_moshi = emel::model::moshi::detail; -using emel::speech::generator::moshi::test::load_fixture_or_skip; -using emel::speech::generator::moshi::test::read_binary_file; -using emel::speech::generator::moshi::test::repo_root; +using emel::speech::predictor::moshi::test::load_fixture_or_skip; +using emel::speech::predictor::moshi::test::read_binary_file; +using emel::speech::predictor::moshi::test::repo_root; inline constexpr emel::error::type k_no_error = emel::error::cast(moshi::error::none); @@ -855,15 +855,15 @@ TEST_CASE("speech_moshi_executor_rejects_graph_step_before_initialize") { TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { const auto bytes = - read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + read_binary_file(repo_root() / "src" / "emel" / "speech" / "predictor" / "moshi" / "executor" / "sm.hpp"); const std::string source{bytes.begin(), bytes.end()}; const auto action_bytes = - read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + read_binary_file(repo_root() / "src" / "emel" / "speech" / "predictor" / "moshi" / "executor" / "actions.hpp"); const std::string actions_source{action_bytes.begin(), action_bytes.end()}; const auto detail_bytes = - read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + read_binary_file(repo_root() / "src" / "emel" / "speech" / "predictor" / "moshi" / "executor" / "detail.hpp"); const std::string detail_source{detail_bytes.begin(), detail_bytes.end()}; @@ -1047,11 +1047,11 @@ TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { TEST_CASE("speech_moshi_generator_graph_outputs_use_explicit_transitions") { const auto action_bytes = - read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + read_binary_file(repo_root() / "src" / "emel" / "speech" / "predictor" / "moshi" / "actions.hpp"); const std::string actions_source{action_bytes.begin(), action_bytes.end()}; const auto sm_bytes = - read_binary_file(repo_root() / "src" / "emel" / "speech" / "generator" / + read_binary_file(repo_root() / "src" / "emel" / "speech" / "predictor" / "moshi" / "sm.hpp"); const std::string sm_source{sm_bytes.begin(), sm_bytes.end()}; diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 7f6f804d..0bcb8daf 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -21,16 +21,16 @@ #include "emel/model/data.hpp" #include "emel/model/detail.hpp" #include "emel/speech/codec/mimi/any.hpp" -#include "emel/speech/generator/moshi/any.hpp" -#include "emel/speech/generator/moshi/executor/any.hpp" #include "emel/speech/generator/sm.hpp" +#include "emel/speech/predictor/moshi/any.hpp" +#include "emel/speech/predictor/moshi/executor/any.hpp" namespace { namespace mimi = emel::speech::codec::mimi; namespace generator = emel::speech::generator; -namespace predictor = emel::speech::generator::moshi; -namespace runtime = emel::speech::generator::moshi::executor; +namespace predictor = emel::speech::predictor::moshi; +namespace runtime = emel::speech::predictor::moshi::executor; struct runner_config { const char *mimi_path = nullptr; From 56a0d4e1ad3e3b4665d7c3572810aa6defca64aa Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 17:53:58 -0500 Subject: [PATCH 14/61] feat: add generic speech synthesis composition --- .../architecture/mermaid/speech_generator.mmd | 62 ---- .planning/architecture/speech_generator.md | 134 --------- README.md | 1 - src/emel/speech/generator/actions.hpp | 136 +++++++++ src/emel/speech/generator/context.hpp | 41 ++- src/emel/speech/generator/errors.hpp | 8 + src/emel/speech/generator/events.hpp | 3 + src/emel/speech/generator/sm.hpp | 264 +++++++++++++++++- tests/speech/generator/lifecycle_tests.cpp | 124 ++++++++ .../bench/speech/personaplex_emel_runner.cpp | 1 + 10 files changed, 575 insertions(+), 199 deletions(-) delete mode 100644 .planning/architecture/mermaid/speech_generator.mmd delete mode 100644 .planning/architecture/speech_generator.md diff --git a/.planning/architecture/mermaid/speech_generator.mmd b/.planning/architecture/mermaid/speech_generator.mmd deleted file mode 100644 index ec3138f4..00000000 --- a/.planning/architecture/mermaid/speech_generator.mmd +++ /dev/null @@ -1,62 +0,0 @@ -stateDiagram-v2 - direction TB - [*] --> state_uninitialized - state_uninitialized --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ - state_ready --> state_initialize_error_ready_channel_decision : initialize_run [always] / already_initialized__ - state_errored --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ - state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_present_] / effect_emit_initialize_done_ - state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_absent_] / none - state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ - state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / none - state_ready --> state_generate_conditioning : generate_run [guard_generate_request_valid_] / effect_prepare_generate_ - state_ready --> state_generate_error_ready_channel_decision : generate_run [guard_generate_request_invalid_] / invalid_request__ - state_generate_conditioning --> state_generate_prefill : completion_generate_run_ [always] / none - state_generate_prefill --> state_generate_predict : completion_generate_run_ [always] / none - state_generate_predict --> state_generate_sample : completion_generate_run_ [always] / none - state_generate_sample --> state_generate_decode : completion_generate_run_ [always] / none - state_generate_decode --> state_generate_postprocess : completion_generate_run_ [always] / none - state_generate_postprocess --> state_generate_error_ready_channel_decision : completion_generate_run_ [always] / cutover_pending__ - state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ - state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / none - state_ready --> state_stream_encode : stream_frame_run [guard_stream_request_valid_] / effect_prepare_stream_frame_ - state_ready --> state_stream_error_ready_channel_decision : stream_frame_run [guard_stream_request_invalid_] / invalid_request__ - state_stream_encode --> state_stream_tokenize : completion_stream_frame_run_ [always] / none - state_stream_tokenize --> state_stream_prefill : completion_stream_frame_run_ [always] / none - state_stream_prefill --> state_stream_predict : completion_stream_frame_run_ [always] / none - state_stream_predict --> state_stream_sample : completion_stream_frame_run_ [always] / none - state_stream_sample --> state_stream_detokenize : completion_stream_frame_run_ [always] / none - state_stream_detokenize --> state_stream_decode : completion_stream_frame_run_ [always] / none - state_stream_decode --> state_stream_postprocess : completion_stream_frame_run_ [always] / none - state_stream_postprocess --> state_stream_error_ready_channel_decision : completion_stream_frame_run_ [always] / cutover_pending__ - state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ - state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / none - state_ready --> state_flush_decode : flush_run [guard_flush_request_valid_] / effect_prepare_flush_ - state_ready --> state_flush_error_ready_channel_decision : flush_run [guard_flush_request_invalid_] / invalid_request__ - state_flush_decode --> state_flush_postprocess : completion_flush_run_ [always] / none - state_flush_postprocess --> state_flush_error_ready_channel_decision : completion_flush_run_ [always] / cutover_pending__ - state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ - state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / none - state_uninitialized --> state_generate_error_uninitialized_channel_decision : generate_run [always] / uninitialized__ - state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ - state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / none - state_uninitialized --> state_stream_error_uninitialized_channel_decision : stream_frame_run [always] / uninitialized__ - state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ - state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / none - state_uninitialized --> state_flush_error_uninitialized_channel_decision : flush_run [always] / uninitialized__ - state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ - state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / none - state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ - state_errored --> state_generate_error_errored_channel_decision : generate_run [always] / internal_error__ - state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ - state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / none - state_errored --> state_stream_error_errored_channel_decision : stream_frame_run [always] / internal_error__ - state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ - state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / none - state_errored --> state_flush_error_errored_channel_decision : flush_run [always] / internal_error__ - state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ - state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / none - state_ready --> state_ready : reset [always] / effect_reset_ - state_errored --> state_ready : reset [always] / effect_reset_ - state_uninitialized --> state_errored : _ [always] / effect_unexpected_ - state_ready --> state_errored : _ [always] / effect_unexpected_ - state_errored --> state_errored : _ [always] / effect_unexpected_ diff --git a/.planning/architecture/speech_generator.md b/.planning/architecture/speech_generator.md deleted file mode 100644 index be28ddd5..00000000 --- a/.planning/architecture/speech_generator.md +++ /dev/null @@ -1,134 +0,0 @@ -# speech_generator - -Source: [`emel/speech/generator/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) - -## Mermaid - -```mermaid -stateDiagram-v2 - direction TB - [*] --> state_uninitialized - state_uninitialized --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ - state_ready --> state_initialize_error_ready_channel_decision : initialize_run [always] / already_initialized__ - state_errored --> state_initialize_done_channel_decision : initialize_run [always] / effect_accept_initialize_ - state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_present_] / effect_emit_initialize_done_ - state_initialize_done_channel_decision --> state_ready : completion_initialize_run_ [guard_initialize_done_callback_absent_] / none - state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ - state_initialize_error_ready_channel_decision --> state_ready : completion_initialize_run_ [initialize_run__] / none - state_ready --> state_generate_conditioning : generate_run [guard_generate_request_valid_] / effect_prepare_generate_ - state_ready --> state_generate_error_ready_channel_decision : generate_run [guard_generate_request_invalid_] / invalid_request__ - state_generate_conditioning --> state_generate_prefill : completion_generate_run_ [always] / none - state_generate_prefill --> state_generate_predict : completion_generate_run_ [always] / none - state_generate_predict --> state_generate_sample : completion_generate_run_ [always] / none - state_generate_sample --> state_generate_decode : completion_generate_run_ [always] / none - state_generate_decode --> state_generate_postprocess : completion_generate_run_ [always] / none - state_generate_postprocess --> state_generate_error_ready_channel_decision : completion_generate_run_ [always] / cutover_pending__ - state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ - state_generate_error_ready_channel_decision --> state_ready : completion_generate_run_ [generate_run__] / none - state_ready --> state_stream_encode : stream_frame_run [guard_stream_request_valid_] / effect_prepare_stream_frame_ - state_ready --> state_stream_error_ready_channel_decision : stream_frame_run [guard_stream_request_invalid_] / invalid_request__ - state_stream_encode --> state_stream_tokenize : completion_stream_frame_run_ [always] / none - state_stream_tokenize --> state_stream_prefill : completion_stream_frame_run_ [always] / none - state_stream_prefill --> state_stream_predict : completion_stream_frame_run_ [always] / none - state_stream_predict --> state_stream_sample : completion_stream_frame_run_ [always] / none - state_stream_sample --> state_stream_detokenize : completion_stream_frame_run_ [always] / none - state_stream_detokenize --> state_stream_decode : completion_stream_frame_run_ [always] / none - state_stream_decode --> state_stream_postprocess : completion_stream_frame_run_ [always] / none - state_stream_postprocess --> state_stream_error_ready_channel_decision : completion_stream_frame_run_ [always] / cutover_pending__ - state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ - state_stream_error_ready_channel_decision --> state_ready : completion_stream_frame_run_ [stream_frame_run__] / none - state_ready --> state_flush_decode : flush_run [guard_flush_request_valid_] / effect_prepare_flush_ - state_ready --> state_flush_error_ready_channel_decision : flush_run [guard_flush_request_invalid_] / invalid_request__ - state_flush_decode --> state_flush_postprocess : completion_flush_run_ [always] / none - state_flush_postprocess --> state_flush_error_ready_channel_decision : completion_flush_run_ [always] / cutover_pending__ - state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ - state_flush_error_ready_channel_decision --> state_ready : completion_flush_run_ [flush_run__] / none - state_uninitialized --> state_generate_error_uninitialized_channel_decision : generate_run [always] / uninitialized__ - state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ - state_generate_error_uninitialized_channel_decision --> state_uninitialized : completion_generate_run_ [generate_run__] / none - state_uninitialized --> state_stream_error_uninitialized_channel_decision : stream_frame_run [always] / uninitialized__ - state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ - state_stream_error_uninitialized_channel_decision --> state_uninitialized : completion_stream_frame_run_ [stream_frame_run__] / none - state_uninitialized --> state_flush_error_uninitialized_channel_decision : flush_run [always] / uninitialized__ - state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ - state_flush_error_uninitialized_channel_decision --> state_uninitialized : completion_flush_run_ [flush_run__] / none - state_uninitialized --> state_uninitialized : reset [always] / uninitialized__ - state_errored --> state_generate_error_errored_channel_decision : generate_run [always] / internal_error__ - state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / effect_emit_generation_error_ - state_generate_error_errored_channel_decision --> state_errored : completion_generate_run_ [generate_run__] / none - state_errored --> state_stream_error_errored_channel_decision : stream_frame_run [always] / internal_error__ - state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / effect_emit_stream_frame_error_ - state_stream_error_errored_channel_decision --> state_errored : completion_stream_frame_run_ [stream_frame_run__] / none - state_errored --> state_flush_error_errored_channel_decision : flush_run [always] / internal_error__ - state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / effect_emit_flush_error_ - state_flush_error_errored_channel_decision --> state_errored : completion_flush_run_ [flush_run__] / none - state_ready --> state_ready : reset [always] / effect_reset_ - state_errored --> state_ready : reset [always] / effect_reset_ - state_uninitialized --> state_errored : _ [always] / effect_unexpected_ - state_ready --> state_errored : _ [always] / effect_unexpected_ - state_errored --> state_errored : _ [always] / effect_unexpected_ -``` - -## Transitions - -| Source | Event | Guard | Action | Target | -| --- | --- | --- | --- | --- | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_accept_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_initialize_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_accept_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_initialize_done_callback_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_initialize_done_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_initialize_done_callback_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_initialize_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_initialize_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_generate_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_prepare_generate>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_conditioning`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_generate_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_conditioning`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`cutover_pending>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_generation_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_stream_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_prepare_stream_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_encode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_stream_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_encode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_prefill`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_predict`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_sample`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_detokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_detokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`cutover_pending>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_stream_frame_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_flush_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_prepare_flush>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`guard_flush_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`invalid_request>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_decode`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_postprocess`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`cutover_pending>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_flush_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_error_ready_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_generation_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_stream_frame_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_flush_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_error_uninitialized_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_generate_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_generation_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_generate_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`generate_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_stream_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_stream_frame_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_stream_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`stream_frame_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`internal_error>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_flush_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_emit_flush_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_flush_error_errored_channel_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`flush_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | -| [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/generator/sm.hpp) | diff --git a/README.md b/README.md index f701290b..9a3be623 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,6 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/speech_codec_mimi.md`](.planning/architecture/speech_codec_mimi.md) - [`.planning/architecture/speech_decoder_whisper.md`](.planning/architecture/speech_decoder_whisper.md) - [`.planning/architecture/speech_encoder_whisper.md`](.planning/architecture/speech_encoder_whisper.md) -- [`.planning/architecture/speech_generator.md`](.planning/architecture/speech_generator.md) - [`.planning/architecture/speech_predictor_moshi_executor.md`](.planning/architecture/speech_predictor_moshi_executor.md) - [`.planning/architecture/speech_predictor_moshi.md`](.planning/architecture/speech_predictor_moshi.md) - [`.planning/architecture/speech_tokenizer_moshi.md`](.planning/architecture/speech_tokenizer_moshi.md) diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index 4d25ee2d..132f9e5f 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -23,6 +23,14 @@ void effect_store_error(const runtime_event_type &runtime_ev, runtime_ev.request.error_out = runtime_ev.ctx.err; } +template +void effect_dispatch_child(const runtime_event_type &runtime_ev, + actor_type &actor, request_type &request) noexcept { + runtime_ev.ctx.child_err = 0; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = actor.process_event(request); +} + template struct effect_initialize_temporal_positions { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { @@ -136,6 +144,67 @@ template struct effect_emit_initialize_error { } }; +template +struct effect_emit_synthesis_initialize_done { + void operator()(const event::initialize_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_done( + events::initialize_done{runtime_ev.request, 0, 0}); + } +}; + +template +struct effect_initialize_synthesis_conditioner { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + auto request = ctx.collaborators.conditioner_initialize; + effect_dispatch_child(runtime_ev, ctx.collaborators.conditioner, request); + } +}; + +template +struct effect_initialize_synthesis_prefiller { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + auto request = ctx.collaborators.prefiller_initialize; + effect_dispatch_child(runtime_ev, ctx.collaborators.prefiller, request); + } +}; + +template +struct effect_initialize_synthesis_predictor { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + auto request = ctx.collaborators.predictor_initialize; + effect_dispatch_child(runtime_ev, ctx.collaborators.predictor, request); + } +}; + +template struct effect_initialize_synthesis_sampler { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + auto request = ctx.collaborators.sampler_initialize; + effect_dispatch_child(runtime_ev, ctx.collaborators.sampler, request); + } +}; + +template struct effect_initialize_synthesis_decoder { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + auto request = ctx.collaborators.decoder_initialize; + effect_dispatch_child(runtime_ev, ctx.collaborators.decoder, request); + } +}; + +template +struct effect_initialize_synthesis_postprocessor { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + auto request = ctx.collaborators.postprocessor_initialize; + effect_dispatch_child(runtime_ev, ctx.collaborators.postprocessor, request); + } +}; + template struct effect_condition_voice { void operator()(const event::condition_run &runtime_ev, context &ctx) const noexcept { @@ -238,6 +307,73 @@ template struct effect_prepare_generate { } }; +template struct effect_condition_generate { + void operator()(const event::generate_run &runtime_ev, + context &ctx) const noexcept { + typename dependencies_type::condition_event request{runtime_ev.request}; + effect_dispatch_child(runtime_ev, ctx.collaborators.conditioner, request); + } +}; + +template struct effect_prefill_generate { + void operator()(const event::generate_run &runtime_ev, + context &ctx) const noexcept { + typename dependencies_type::prefill_event request{runtime_ev.request}; + effect_dispatch_child(runtime_ev, ctx.collaborators.prefiller, request); + } +}; + +template struct effect_predict_generate { + void operator()(const event::generate_run &runtime_ev, + context &ctx) const noexcept { + typename dependencies_type::predict_event request{runtime_ev.request}; + effect_dispatch_child(runtime_ev, ctx.collaborators.predictor, request); + } +}; + +template struct effect_sample_generate { + void operator()(const event::generate_run &runtime_ev, + context &ctx) const noexcept { + typename dependencies_type::sample_event request{runtime_ev.request}; + effect_dispatch_child(runtime_ev, ctx.collaborators.sampler, request); + } +}; + +template struct effect_decode_generate { + void operator()(const event::generate_run &runtime_ev, + context &ctx) const noexcept { + typename dependencies_type::decode_event request{ + runtime_ev.request, runtime_ev.ctx.sample_count}; + effect_dispatch_child(runtime_ev, ctx.collaborators.decoder, request); + } +}; + +template struct effect_postprocess_generate { + void operator()(const event::generate_run &runtime_ev, + context &ctx) const noexcept { + typename dependencies_type::postprocess_event request{ + runtime_ev.request, runtime_ev.ctx.sample_count}; + effect_dispatch_child(runtime_ev, ctx.collaborators.postprocessor, request); + } +}; + +template struct effect_publish_generation_done { + void operator()(const event::generate_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.sample_count_out = runtime_ev.ctx.sample_count; + runtime_ev.ctx.err = error_code(error::none); + runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + +template struct effect_emit_generation_done { + void operator()(const event::generate_run &runtime_ev, + const context &) const noexcept { + runtime_ev.request.on_done(events::generation_done{ + runtime_ev.request, runtime_ev.request.sample_count_out}); + } +}; + template struct effect_fail_generate { void operator()(const event::generate_run &runtime_ev, diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index 338f1212..104da5cd 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -1,9 +1,20 @@ #pragma once +#include + namespace emel::speech::generator::action { +namespace mode { + +struct duplex {}; +struct synthesis {}; + +} // namespace mode + template -concept generator_dependencies = requires(dependencies_type deps) { +concept duplex_dependencies = requires(dependencies_type deps) { + requires std::same_as; typename dependencies_type::voice_condition_event; typename dependencies_type::prompt_begin_event; typename dependencies_type::prompt_condition_event; @@ -28,6 +39,34 @@ concept generator_dependencies = requires(dependencies_type deps) { deps.codebook_count; }; +template +concept synthesis_dependencies = requires(dependencies_type deps) { + requires std::same_as; + typename dependencies_type::condition_event; + typename dependencies_type::prefill_event; + typename dependencies_type::predict_event; + typename dependencies_type::sample_event; + typename dependencies_type::decode_event; + typename dependencies_type::postprocess_event; + deps.conditioner; + deps.prefiller; + deps.predictor; + deps.sampler; + deps.decoder; + deps.postprocessor; + deps.conditioner_initialize; + deps.prefiller_initialize; + deps.predictor_initialize; + deps.sampler_initialize; + deps.decoder_initialize; + deps.postprocessor_initialize; +}; + +template +concept generator_dependencies = duplex_dependencies || + synthesis_dependencies; + template struct context { explicit context(const dependencies_type &deps) noexcept : collaborators(deps) {} diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp index a462924d..c6861975 100644 --- a/src/emel/speech/generator/errors.hpp +++ b/src/emel/speech/generator/errors.hpp @@ -20,6 +20,14 @@ enum class error : emel::error::type { encode_failed = (1u << 11), predict_failed = (1u << 12), decode_failed = (1u << 13), + conditioner_initialize_failed = (1u << 14), + prefiller_initialize_failed = (1u << 15), + sampler_initialize_failed = (1u << 16), + postprocessor_initialize_failed = (1u << 17), + prefill_failed = (1u << 18), + sample_failed = (1u << 19), + postprocess_failed = (1u << 20), + unsupported_request = (1u << 21), }; } // namespace emel::speech::generator diff --git a/src/emel/speech/generator/events.hpp b/src/emel/speech/generator/events.hpp index eab50fed..481937e4 100644 --- a/src/emel/speech/generator/events.hpp +++ b/src/emel/speech/generator/events.hpp @@ -135,6 +135,9 @@ struct condition_ctx { struct generate_ctx { emel::error::type err = {}; + emel::error::type child_err = {}; + bool child_accepted = false; + int32_t sample_count = 0; }; struct frame_ctx { diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index 095d64b3..112a1860 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -20,6 +20,12 @@ struct state_initialize_decoder_result {}; struct state_initialize_runtime_result {}; struct state_initialize_predictor_result {}; struct state_initialize_conditioning_result {}; +struct state_initialize_synthesis_conditioner_result {}; +struct state_initialize_synthesis_prefiller_result {}; +struct state_initialize_synthesis_predictor_result {}; +struct state_initialize_synthesis_sampler_result {}; +struct state_initialize_synthesis_decoder_result {}; +struct state_initialize_synthesis_postprocessor_result {}; struct state_initialize_done_channel_decision {}; struct state_initialize_error_channel_decision {}; @@ -40,6 +46,7 @@ struct state_generate_sample {}; struct state_generate_decode {}; struct state_generate_postprocess {}; struct state_generate_error_channel_decision {}; +struct state_generate_done_channel_decision {}; struct state_stream_encode_result {}; struct state_stream_predict_result {}; @@ -77,7 +84,7 @@ control invariants - request-local status stays in typed runtime events. Context owns only the persistent injected composition. */ -template struct model { +template struct duplex_model { auto operator()() const { namespace sml = stateforward::sml; @@ -436,6 +443,261 @@ template struct model { } }; +/* +generic offline synthesis composition + +- the dependency mode selects this graph at compile time; there is no runtime + route, callback table, or model-family test. +- each synthesis stage is a separately injected actor. Child acceptance and + error results are interpreted only by guards and transitions. +- condition, stream_frame, and flush remain distinct public requests and are + explicitly rejected by a synthesis-only composition. +*/ +template struct synthesis_model { + auto operator()() const { + namespace sml = stateforward::sml; + + using init_run = event::initialize_run; + using condition_run = event::condition_run; + using generate_run = event::generate_run; + using stream_run = event::stream_frame_run; + using flush_run = event::flush_run; + using init_done_present = + guard::guard_done_callback_present; + using init_done_absent = + guard::guard_done_callback_absent; + using init_error_present = + guard::guard_error_callback_present; + using init_error_absent = + guard::guard_error_callback_absent; + using generate_done_present = + guard::guard_done_callback_present; + using generate_done_absent = + guard::guard_done_callback_absent; + using generate_error_present = + guard::guard_error_callback_present; + using generate_error_absent = + guard::guard_error_callback_absent; + using condition_error_present = + guard::guard_error_callback_present; + using condition_error_absent = + guard::guard_error_callback_absent; + using stream_error_present = + guard::guard_error_callback_present; + using stream_error_absent = + guard::guard_error_callback_absent; + using flush_error_present = + guard::guard_error_callback_present; + using flush_error_absent = + guard::guard_error_callback_absent; + + // clang-format off + return sml::make_transition_table( + //------------------------------------------------------------------------------// + // Injected offline-synthesis actor initialization. + sml::state <= + *sml::state + sml::event + / action::effect_initialize_synthesis_conditioner{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_synthesis_prefiller{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_synthesis_predictor{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_synthesis_sampler{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_synthesis_decoder{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_initialize_synthesis_postprocessor{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_initialize_done{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ init_done_present{} ] + / action::effect_emit_synthesis_initialize_done{} + , sml::state <= + sml::state + sml::completion + [ init_done_absent{} ] + , sml::state <= + sml::state + sml::completion + [ init_error_present{} ] / action::effect_emit_initialize_error{} + , sml::state <= + sml::state + sml::completion + [ init_error_absent{} ] + + //------------------------------------------------------------------------------// + // Offline condition -> prefill -> predict -> sample -> decode -> postprocess. + , sml::state <= sml::state + + sml::event [ guard::guard_generate_request_valid{} ] + / action::effect_condition_generate{} + , sml::state <= sml::state + + sml::event [ guard::guard_generate_request_invalid{} ] + / action::effect_fail_generate{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_prefill_generate{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_generate{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_predict_generate{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_generate{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_sample_generate{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_generate{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_decode_generate{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_generate{} + , sml::state <= sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_postprocess_generate{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_generate{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_generation_done{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_generate{} + , sml::state <= sml::state + + sml::completion [ generate_done_present{} ] + / action::effect_emit_generation_done{} + , sml::state <= sml::state + + sml::completion [ generate_done_absent{} ] + , sml::state <= sml::state + + sml::completion [ generate_error_present{} ] + / action::effect_emit_generation_error{} + , sml::state <= sml::state + + sml::completion [ generate_error_absent{} ] + + //------------------------------------------------------------------------------// + // Public request shapes not implemented by a synthesis-only composition. + , sml::state <= sml::state + + sml::event + / action::effect_fail_condition{} + , sml::state <= sml::state + + sml::completion [ condition_error_present{} ] + / action::effect_emit_condition_error{} + , sml::state <= sml::state + + sml::completion [ condition_error_absent{} ] + , sml::state <= sml::state + + sml::event + / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ stream_error_present{} ] + / action::effect_emit_stream_frame_error{} + , sml::state <= sml::state + + sml::completion [ stream_error_absent{} ] + , sml::state <= sml::state + + sml::event + / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ flush_error_present{} ] + / action::effect_emit_flush_error{} + , sml::state <= sml::state + + sml::completion [ flush_error_absent{} ] + + //------------------------------------------------------------------------------// + // Lifecycle errors remain explicit. + , sml::state <= sml::state + + sml::event + / action::effect_reject_reset{} + , sml::state <= sml::state + sml::event + / action::effect_reject_reset{} + , sml::state <= sml::state + sml::event + / action::effect_reject_reset{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} + ); + // clang-format on + } +}; + +template +struct model; + +template +struct model + : duplex_model {}; + +template +struct model + : synthesis_model {}; + template struct sm : public emel::sm, action::context> { diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index 00c6032b..f139b420 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -198,6 +198,7 @@ struct fake_predictor_actor { }; struct fake_dependencies { + using generator_mode = generator::action::mode::duplex; using voice_condition_event = fake_voice_condition; using prompt_begin_event = fake_prompt_begin; using prompt_condition_event = fake_prompt_condition; @@ -296,6 +297,9 @@ struct callback_probe { ++error_calls; last_error = ev.err; } + void generation_done(const generator::events::generation_done &) noexcept { + ++done_calls; + } void stream_done(const generator::events::stream_frame_done &) noexcept { ++done_calls; } @@ -318,6 +322,90 @@ void advance_to_ready(fixture &test) { REQUIRE(test.condition()); } +struct fake_synthesis_stage { + explicit fake_synthesis_stage( + const generator::event::generate &request_ref) noexcept + : request(request_ref) {} + fake_synthesis_stage(const generator::event::generate &request_ref, + int32_t &sample_count_out_ref) noexcept + : request(request_ref), sample_count_out(&sample_count_out_ref) {} + + const generator::event::generate &request; + int32_t *sample_count_out = nullptr; + emel::error::type *error_out = nullptr; +}; + +struct fake_synthesis_actor { + int32_t initialize_calls = 0; + int32_t stage_calls = 0; + bool write_pcm = false; + bool postprocess_pcm = false; + + bool process_event(const fake_initialize &request) noexcept { + ++initialize_calls; + *request.error_out = 0; + return true; + } + + bool process_event(const fake_synthesis_stage &request) noexcept { + ++stage_calls; + if (write_pcm) { + std::fill(request.request.pcm_out.begin(), request.request.pcm_out.end(), + 0.5f); + *request.sample_count_out = + static_cast(request.request.pcm_out.size()); + } + if (postprocess_pcm) { + for (float &sample : request.request.pcm_out) { + sample *= 0.5f; + } + } + *request.error_out = 0; + return true; + } +}; + +struct fake_synthesis_dependencies { + using generator_mode = generator::action::mode::synthesis; + using condition_event = fake_synthesis_stage; + using prefill_event = fake_synthesis_stage; + using predict_event = fake_synthesis_stage; + using sample_event = fake_synthesis_stage; + using decode_event = fake_synthesis_stage; + using postprocess_event = fake_synthesis_stage; + + fake_synthesis_actor &conditioner; + fake_synthesis_actor &prefiller; + fake_synthesis_actor &predictor; + fake_synthesis_actor &sampler; + fake_synthesis_actor &decoder; + fake_synthesis_actor &postprocessor; + fake_initialize conditioner_initialize = {}; + fake_initialize prefiller_initialize = {}; + fake_initialize predictor_initialize = {}; + fake_initialize sampler_initialize = {}; + fake_initialize decoder_initialize = {}; + fake_initialize postprocessor_initialize = {}; +}; + +struct synthesis_fixture { + fake_synthesis_actor conditioner{}; + fake_synthesis_actor prefiller{}; + fake_synthesis_actor predictor{}; + fake_synthesis_actor sampler{}; + fake_synthesis_actor decoder{.write_pcm = true}; + fake_synthesis_actor postprocessor{.postprocess_pcm = true}; + fake_synthesis_dependencies dependencies{ + .conditioner = conditioner, + .prefiller = prefiller, + .predictor = predictor, + .sampler = sampler, + .decoder = decoder, + .postprocessor = postprocessor, + }; + generator::sm machine{dependencies}; +}; + } // namespace TEST_CASE("speech_generator_initializes_injected_actor_composition") { @@ -331,6 +419,42 @@ TEST_CASE("speech_generator_initializes_injected_actor_composition") { CHECK(test->predictor.initialize_calls == 2); } +TEST_CASE("speech_generator_synthesizes_with_model_neutral_actor_composition") { + auto test = std::make_unique(); + emel::error::type err = -1; + REQUIRE(test->machine.process_event(generator::event::initialize{err})); + CHECK(test->machine.is(sml::state)); + CHECK(test->conditioner.initialize_calls == 1); + CHECK(test->prefiller.initialize_calls == 1); + CHECK(test->predictor.initialize_calls == 1); + CHECK(test->sampler.initialize_calls == 1); + CHECK(test->decoder.initialize_calls == 1); + CHECK(test->postprocessor.initialize_calls == 1); + + callback_probe probe{}; + std::array pcm_out{}; + int32_t sample_count = 0; + generator::event::generate request{"a model-neutral synthesis request", + std::span{pcm_out}, sample_count, + err}; + request.on_done = + decltype(request.on_done)::from(&probe); + + REQUIRE(test->machine.process_event(request)); + CHECK(test->machine.is(sml::state)); + CHECK(test->conditioner.stage_calls == 1); + CHECK(test->prefiller.stage_calls == 1); + CHECK(test->predictor.stage_calls == 1); + CHECK(test->sampler.stage_calls == 1); + CHECK(test->decoder.stage_calls == 1); + CHECK(test->postprocessor.stage_calls == 1); + CHECK(sample_count == 8); + CHECK(pcm_out[0] == doctest::Approx(0.25f)); + CHECK(probe.done_calls == 1); + CHECK(err == generator::action::error_code(generator::error::none)); +} + TEST_CASE("speech_generator_reports_initialize_outcomes_through_callbacks") { SUBCASE("success") { auto test = std::make_unique(); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 0bcb8daf..6bdad5ee 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -89,6 +89,7 @@ bool bind_secondary_cache(void *binding_ptr, const emel::model::data &, } struct personaplex_dependencies { + using generator_mode = generator::action::mode::duplex; using voice_condition_event = predictor::event::prefill_voice; using prompt_begin_event = predictor::event::begin_personaplex_prompt; using prompt_condition_event = predictor::event::prefill_personaplex_prompt; From c115bdd0070701d1ba4184932b5497fb7a7ece5f Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 18:46:41 -0500 Subject: [PATCH 15/61] refactor: expose moshi token phases to speech generator --- src/emel/speech/generator/actions.hpp | 89 +++++++++++++- src/emel/speech/generator/context.hpp | 10 ++ src/emel/speech/generator/errors.hpp | 3 + src/emel/speech/generator/events.hpp | 5 + src/emel/speech/generator/guards.hpp | 19 +++ src/emel/speech/generator/sm.hpp | 97 ++++++++++++--- src/emel/speech/predictor/moshi/actions.hpp | 116 +++++++++++++++--- src/emel/speech/predictor/moshi/events.hpp | 45 +++++++ src/emel/speech/predictor/moshi/guards.hpp | 46 +++++++ src/emel/speech/predictor/moshi/sm.hpp | 113 ++++++++++++++++- tests/speech/generator/lifecycle_tests.cpp | 108 +++++++++++++++- .../bench/speech/personaplex_emel_runner.cpp | 60 ++++++++- 12 files changed, 663 insertions(+), 48 deletions(-) diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index 132f9e5f..6c06e796 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -111,6 +111,19 @@ template struct effect_initialize_conditioning { } }; +template struct effect_initialize_tokenizer { + void operator()(const event::initialize_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.tokenizer_err = 0; + typename dependencies_type::tokenizer_initialize_event request{ + runtime_ev.ctx.tokenizer_err}; + runtime_ev.ctx.child_accepted = + ctx.collaborators.tokenizer.process_event(request); + runtime_ev.ctx.child_err = + static_cast(runtime_ev.ctx.tokenizer_err); + } +}; + template struct effect_publish_initialize_done { void operator()(const event::initialize_run &runtime_ev, const context &) const noexcept { @@ -251,6 +264,33 @@ template struct effect_condition_prompt { } }; +template struct effect_capture_tokenizer_state { + void operator()(const event::condition_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.tokenizer_offset = 0; + typename dependencies_type::capture_tokenizer_state_event request{ + ctx.collaborators.tokenizer_cache_snapshot, + runtime_ev.ctx.tokenizer_offset, runtime_ev.ctx.child_err}; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template struct effect_restore_tokenizer_state { + void operator()(const event::condition_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.tokenizer_err = 0; + typename dependencies_type::restore_tokenizer_state_event request{ + std::span{ctx.collaborators.tokenizer_cache_snapshot}, + runtime_ev.ctx.tokenizer_offset, runtime_ev.ctx.tokenizer_err}; + runtime_ev.ctx.child_accepted = + ctx.collaborators.tokenizer.process_event(request); + runtime_ev.ctx.child_err = + static_cast(runtime_ev.ctx.tokenizer_err); + } +}; + template struct effect_publish_condition_pending { void operator()(const event::condition_run &runtime_ev, const context &) const noexcept { @@ -416,26 +456,63 @@ template struct effect_encode_flush_frame { } }; +template +struct effect_tokenize_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.tokenizer_err = 0; + typename dependencies_type::tokenize_event request{ + ctx.collaborators.tokenize_input_codes, ctx.collaborators.model_codes, + runtime_ev.ctx.tokenizer_err}; + runtime_ev.ctx.child_accepted = + ctx.collaborators.tokenizer.process_event(request); + runtime_ev.ctx.child_err = + static_cast(runtime_ev.ctx.tokenizer_err); + } +}; + template struct effect_predict_frame { void operator()(const runtime_event_type &runtime_ev, context &ctx) const noexcept { runtime_ev.ctx.child_err = 0; runtime_ev.ctx.graph_err = 0; - runtime_ev.ctx.produced = false; - std::fill(ctx.collaborators.output_codes.begin(), - ctx.collaborators.output_codes.end(), -1); + runtime_ev.ctx.predicted_text_token = -1; + std::fill(ctx.collaborators.predicted_codes.begin(), + ctx.collaborators.predicted_codes.end(), -1); typename dependencies_type::predict_event request{ - std::span{ctx.collaborators.input_codes}, - ctx.collaborators.output_codes, runtime_ev.ctx.text_token}; + std::span{ctx.collaborators.model_codes}, + ctx.collaborators.predicted_codes, runtime_ev.ctx.predicted_text_token}; request.error_out = &runtime_ev.ctx.child_err; request.graph_error_out = &runtime_ev.ctx.graph_err; - request.produced_out = &runtime_ev.ctx.produced; runtime_ev.ctx.child_accepted = ctx.collaborators.predictor.process_event(request); } }; +template +struct effect_detokenize_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.tokenizer_err = 0; + runtime_ev.ctx.produced = false; + runtime_ev.ctx.text_token = -1; + std::fill(ctx.collaborators.output_codes.begin(), + ctx.collaborators.output_codes.end(), -1); + typename dependencies_type::detokenize_event request{ + runtime_ev.ctx.predicted_text_token, + std::span{ctx.collaborators.predicted_codes}, + runtime_ev.ctx.text_token, + ctx.collaborators.output_codes, + runtime_ev.ctx.produced, + runtime_ev.ctx.tokenizer_err}; + runtime_ev.ctx.child_accepted = + ctx.collaborators.tokenizer.process_event(request); + runtime_ev.ctx.child_err = + static_cast(runtime_ev.ctx.tokenizer_err); + } +}; + template struct effect_decode_frame { void operator()(const runtime_event_type &runtime_ev, diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index 104da5cd..14909881 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -19,11 +19,17 @@ concept duplex_dependencies = requires(dependencies_type deps) { typename dependencies_type::prompt_begin_event; typename dependencies_type::prompt_condition_event; typename dependencies_type::encode_event; + typename dependencies_type::tokenizer_initialize_event; + typename dependencies_type::tokenize_event; typename dependencies_type::predict_event; + typename dependencies_type::detokenize_event; + typename dependencies_type::capture_tokenizer_state_event; + typename dependencies_type::restore_tokenizer_state_event; typename dependencies_type::decode_event; deps.temporal_positions; deps.secondary_positions; deps.encoder; + deps.tokenizer; deps.decoder; deps.runtime; deps.predictor; @@ -34,7 +40,11 @@ concept duplex_dependencies = requires(dependencies_type deps) { deps.conditioning_initialize; deps.silence_pcm; deps.input_codes; + deps.tokenize_input_codes; + deps.model_codes; + deps.predicted_codes; deps.output_codes; + deps.tokenizer_cache_snapshot; deps.frame_samples; deps.codebook_count; }; diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp index c6861975..b307c48d 100644 --- a/src/emel/speech/generator/errors.hpp +++ b/src/emel/speech/generator/errors.hpp @@ -28,6 +28,9 @@ enum class error : emel::error::type { sample_failed = (1u << 19), postprocess_failed = (1u << 20), unsupported_request = (1u << 21), + tokenizer_initialize_failed = (1u << 22), + tokenize_failed = (1u << 23), + detokenize_failed = (1u << 24), }; } // namespace emel::speech::generator diff --git a/src/emel/speech/generator/events.hpp b/src/emel/speech/generator/events.hpp index 481937e4..6a019a44 100644 --- a/src/emel/speech/generator/events.hpp +++ b/src/emel/speech/generator/events.hpp @@ -122,6 +122,7 @@ struct initialize_ctx { emel::error::type err = {}; emel::error::type child_err = {}; bool child_accepted = false; + int32_t tokenizer_err = 0; }; struct condition_ctx { @@ -131,6 +132,8 @@ struct condition_ctx { bool child_accepted = false; bool complete = false; int32_t remaining = -1; + int32_t tokenizer_err = 0; + int64_t tokenizer_offset = 0; }; struct generate_ctx { @@ -146,6 +149,8 @@ struct frame_ctx { emel::error::type graph_err = {}; bool child_accepted = false; bool produced = false; + int32_t tokenizer_err = 0; + int32_t predicted_text_token = -1; int32_t text_token = -1; }; diff --git a/src/emel/speech/generator/guards.hpp b/src/emel/speech/generator/guards.hpp index 912f5d0b..92a746d6 100644 --- a/src/emel/speech/generator/guards.hpp +++ b/src/emel/speech/generator/guards.hpp @@ -138,6 +138,25 @@ struct guard_frame_produced { } }; +template +struct guard_prediction_succeeded { + bool operator()(const runtime_event_type &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.child_accepted && runtime_ev.ctx.child_err == 0 && + runtime_ev.ctx.graph_err == 0; + } +}; + +template +struct guard_prediction_failed { + bool + operator()(const runtime_event_type &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_prediction_succeeded{}( + runtime_ev, ctx); + } +}; + template struct guard_frame_pending { bool operator()(const runtime_event_type &runtime_ev, diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index 112a1860..cb4a3da2 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -20,6 +20,7 @@ struct state_initialize_decoder_result {}; struct state_initialize_runtime_result {}; struct state_initialize_predictor_result {}; struct state_initialize_conditioning_result {}; +struct state_initialize_tokenizer_result {}; struct state_initialize_synthesis_conditioner_result {}; struct state_initialize_synthesis_prefiller_result {}; struct state_initialize_synthesis_predictor_result {}; @@ -35,6 +36,8 @@ struct state_condition_prompt_begin_result {}; struct state_condition_voice_done_channel_decision {}; struct state_condition_prompt {}; struct state_condition_prompt_result {}; +struct state_condition_capture_tokenizer_result {}; +struct state_condition_restore_tokenizer_result {}; struct state_condition_prompt_done_channel_decision {}; struct state_condition_error_channel_decision {}; @@ -49,14 +52,18 @@ struct state_generate_error_channel_decision {}; struct state_generate_done_channel_decision {}; struct state_stream_encode_result {}; +struct state_stream_tokenize_result {}; struct state_stream_predict_result {}; +struct state_stream_detokenize_result {}; struct state_stream_decode_result {}; struct state_stream_done_channel_decision {}; struct state_stream_error_channel_decision {}; struct state_flushing {}; struct state_flush_encode_result {}; +struct state_flush_tokenize_result {}; struct state_flush_predict_result {}; +struct state_flush_detokenize_result {}; struct state_flush_decode_result {}; struct state_flush_done_channel_decision {}; struct state_flush_error_channel_decision {}; @@ -186,14 +193,22 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_initialize{} - , sml::state <= + , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_publish_initialize_done{} + / action::effect_initialize_tokenizer{} , sml::state <= sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_initialize{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_initialize_done{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_initialize{} , sml::state <= sml::state + sml::completion [ init_done_present{} ] / action::effect_emit_initialize_done{} @@ -255,14 +270,34 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_condition_succeeded_pending{} ] / action::effect_publish_condition_pending{} - , sml::state <= + , sml::state <= sml::state + sml::completion [ guard::guard_condition_succeeded_complete{} ] - / action::effect_publish_condition_complete{} + / action::effect_capture_tokenizer_state{} , sml::state <= sml::state + sml::completion [ guard::guard_condition_failed{} ] / action::effect_fail_condition{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_restore_tokenizer_state{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_condition{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_succeeded{} ] + / action::effect_publish_condition_complete{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_condition{} , sml::state <= sml::state + sml::completion @@ -317,31 +352,45 @@ template struct duplex_model { + sml::completion [ generate_error_absent{} ] //------------------------------------------------------------------------------// - // Duplex encode -> predict -> optional decode. + // Duplex encode -> tokenize -> predict -> detokenize -> optional decode. , sml::state <= sml::state + sml::event [ guard::guard_stream_request_valid{} ] / action::effect_encode_stream_frame{} , sml::state <= sml::state + sml::event [ guard::guard_stream_request_invalid{} ] / action::effect_fail_stream_frame{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_predict_frame{} + / action::effect_tokenize_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_stream_frame{} - , sml::state <= sml::state + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_predict_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_prediction_succeeded{} ] + / action::effect_detokenize_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_prediction_failed{} ] + / action::effect_fail_stream_frame{} + , sml::state <= sml::state + sml::completion [ guard::guard_frame_produced{} ] / action::effect_decode_frame{} , sml::state <= - sml::state + sml::completion + sml::state + sml::completion [ guard::guard_frame_pending{} ] / action::effect_publish_stream_frame_pending{} , sml::state <= - sml::state + sml::completion + sml::state + sml::completion [ guard::guard_frame_failed{} ] - / action::effect_fail_stream_frame{} + / action::effect_fail_stream_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] @@ -375,24 +424,38 @@ template struct duplex_model { , sml::state <= sml::state + sml::event [ guard::guard_flush_request_invalid{} ] / action::effect_fail_flush{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_predict_frame{} + / action::effect_tokenize_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_flush{} - , sml::state <= sml::state + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_predict_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ guard::guard_prediction_succeeded{} ] + / action::effect_detokenize_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_prediction_failed{} ] + / action::effect_fail_flush{} + , sml::state <= sml::state + sml::completion [ guard::guard_frame_produced{} ] / action::effect_decode_frame{} , sml::state <= - sml::state + sml::completion + sml::state + sml::completion [ guard::guard_frame_pending{} ] / action::effect_publish_flush_pending{} , sml::state <= - sml::state + sml::completion + sml::state + sml::completion [ guard::guard_frame_failed{} ] - / action::effect_fail_flush{} + / action::effect_fail_flush{} , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index 5ed4d981..9a43b25b 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -29,6 +29,15 @@ template struct effect_mark_not_initialized { } }; +template +struct effect_mark_not_initialized_and_store { + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::not_initialized); + *runtime_ev.request.error_out = runtime_ev.ctx.err; + } +}; + struct effect_mark_bind_failed { void operator()(const event::initialize_run &runtime_ev, context &) const noexcept { @@ -44,8 +53,11 @@ template struct effect_mark_memory_error { }; struct effect_mark_step_request_invalid { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::request_shape); + template + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + ev.ctx.err = detail_ns::to_error(error::request_shape); } }; @@ -80,8 +92,11 @@ struct effect_mark_personaplex_prompt_error { }; struct effect_mark_voice_prompt_pending { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::voice_prompt_pending); + template + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + ev.ctx.err = detail_ns::to_error(error::voice_prompt_pending); } }; @@ -180,17 +195,19 @@ struct effect_allocate_sequence { }; struct effect_allocate_step_slot { - void operator()(const event::step_run &runtime_ev, + template + void operator()(const runtime_event_type &runtime_ev, context &ctx) const noexcept { - runtime_ev.ctx.memory_error = static_cast( + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + ev.ctx.memory_error = static_cast( emel::error::cast(emel::memory::hybrid::error::none)); - runtime_ev.ctx.memory_block_count = 0; - runtime_ev.ctx.memory_accepted = + ev.ctx.memory_block_count = 0; + ev.ctx.memory_accepted = ctx.memory.process_event(emel::memory::event::allocate_slots{ .seq_id = ctx.session.sequence_id, .token_count = 1, - .block_count_out = &runtime_ev.ctx.memory_block_count, - .error_out = &runtime_ev.ctx.memory_error, + .block_count_out = &ev.ctx.memory_block_count, + .error_out = &ev.ctx.memory_error, .copy_block = nullptr, .copy_block_user_data = nullptr, }); @@ -198,14 +215,16 @@ struct effect_allocate_step_slot { }; struct effect_capture_memory { - void operator()(const event::step_run &runtime_ev, + template + void operator()(const runtime_event_type &runtime_ev, context &ctx) const noexcept { - runtime_ev.ctx.memory_error = static_cast( + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + ev.ctx.memory_error = static_cast( emel::error::cast(emel::memory::hybrid::error::none)); - runtime_ev.ctx.memory_accepted = + ev.ctx.memory_accepted = ctx.memory.process_event(emel::memory::event::capture_view{ - .snapshot_out = &runtime_ev.ctx.memory_snapshot, - .error_out = &runtime_ev.ctx.memory_error, + .snapshot_out = &ev.ctx.memory_snapshot, + .error_out = &ev.ctx.memory_error, }); } }; @@ -602,6 +621,73 @@ struct effect_begin_step { } }; +struct effect_begin_predict { + void operator()(const event::predict_run &runtime_ev, + const context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_accepted = false; + } +}; + +struct effect_run_predict_graph { + void operator()(const event::predict_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + event::graph_step graph_step{ + *ctx.session.model, + runtime_ev.ctx.memory_snapshot, + runtime_ev.request.model_tokens, + runtime_ev.request.audio_tokens_out, + runtime_ev.request.text_token_out, + }; + graph_step.sequence_id = ctx.session.sequence_id; + graph_step.error_out = &runtime_ev.ctx.graph_error; + runtime_ev.ctx.graph_accepted = + ctx.graph.dispatch_step(ctx.graph.executor, graph_step); + } +}; + +struct effect_publish_predict { + void operator()(const event::predict_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + } +}; + +struct effect_store_predict_graph_error_out { + void operator()(const event::predict_run &runtime_ev, + context &) const noexcept { + *runtime_ev.request.graph_error_out = runtime_ev.ctx.graph_error; + } +}; + +struct effect_capture_tokenizer_state { + void operator()(const event::capture_tokenizer_state &ev, + const context &ctx) const noexcept { + for (int32_t codebook = 0; codebook < ctx.lmgen.codebook_count; + ++codebook) { + for (int32_t row = 0; row < ctx.lmgen.cache_row_count; ++row) { + const size_t destination = + static_cast(row) + + static_cast(codebook) * + static_cast(ctx.lmgen.cache_row_count); + ev.cache_out[destination] = detail::cache_at(ctx.lmgen, row, codebook); + } + } + ev.offset_out = ctx.lmgen.offset; + ev.error_out = detail_ns::to_error(error::none); + } +}; + +template struct effect_reject_capture_tokenizer_state { + void operator()(const event::capture_tokenizer_state &ev, + const context &) const noexcept { + ev.offset_out = 0; + ev.error_out = detail_ns::to_error(error_value); + } +}; + struct effect_write_full_input { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 8de23247..d7ceb840 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -106,6 +106,32 @@ struct step { emel::callback on_error = {}; }; +struct predict { + predict(std::span model_tokens_ref, + std::span audio_tokens_out_ref, + int32_t &text_token_out_ref) noexcept + : model_tokens(model_tokens_ref), audio_tokens_out(audio_tokens_out_ref), + text_token_out(text_token_out_ref) {} + + std::span model_tokens = {}; + std::span audio_tokens_out = {}; + int32_t &text_token_out; + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; +}; + +struct capture_tokenizer_state { + capture_tokenizer_state(std::span cache_out_ref, + int64_t &offset_out_ref, + emel::error::type &error_out_ref) noexcept + : cache_out(cache_out_ref), offset_out(offset_out_ref), + error_out(error_out_ref) {} + + std::span cache_out = {}; + int64_t &offset_out; + emel::error::type &error_out; +}; + struct reset {}; struct graph_step { @@ -207,6 +233,20 @@ struct step_ctx { emel::memory::view::snapshot &memory_snapshot; }; +struct predict_ctx { + explicit predict_ctx( + emel::memory::view::snapshot &memory_snapshot_ref) noexcept + : memory_snapshot(memory_snapshot_ref) {} + + emel::error::type err = emel::error::cast(error::none); + bool memory_accepted = false; + int32_t memory_error = static_cast(emel::error::cast(error::none)); + int32_t memory_block_count = 0; + bool graph_accepted = false; + emel::error::type graph_error = emel::error::cast(error::none); + emel::memory::view::snapshot &memory_snapshot; +}; + struct initialize_run { const initialize &request; initialize_ctx &ctx; @@ -237,6 +277,11 @@ struct step_run { step_ctx &ctx; }; +struct predict_run { + const predict &request; + predict_ctx &ctx; +}; + struct reset_run { const reset &request; }; diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 46d2da8e..69c4ca0d 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -172,6 +172,52 @@ struct guard_step_request_shape_invalid { } }; +struct guard_predict_request_valid { + bool operator()(const event::predict_run &runtime_ev, + const action::context &ctx) const noexcept { + const bool voice_ready = + !ctx.voice.loaded || (ctx.voice.ready && ctx.voice.prompt_ready); + return ctx.session.model != nullptr && voice_ready && + runtime_ev.request.model_tokens.size() == + static_cast(ctx.lmgen.codebook_count) && + runtime_ev.request.audio_tokens_out.size() >= + static_cast(ctx.lmgen.generated_dep_q); + } +}; + +struct guard_predict_blocked_by_voice_prompt { + bool operator()(const event::predict_run &, + const action::context &ctx) const noexcept { + return ctx.session.model != nullptr && ctx.voice.loaded && + (!ctx.voice.ready || !ctx.voice.prompt_ready); + } +}; + +struct guard_predict_request_shape_invalid { + bool operator()(const event::predict_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_predict_request_valid{}(runtime_ev, ctx) && + !guard_predict_blocked_by_voice_prompt{}(runtime_ev, ctx); + } +}; + +struct guard_capture_tokenizer_state_valid { + bool operator()(const event::capture_tokenizer_state &ev, + const action::context &ctx) const noexcept { + return ctx.session.model != nullptr && + ev.cache_out.size() == + static_cast(ctx.lmgen.cache_row_count * + ctx.lmgen.codebook_count); + } +}; + +struct guard_capture_tokenizer_state_invalid { + bool operator()(const event::capture_tokenizer_state &ev, + const action::context &ctx) const noexcept { + return !guard_capture_tokenizer_state_valid{}(ev, ctx); + } +}; + struct guard_voice_prefill_request_valid { bool operator()(const event::prefill_voice_run &, const action::context &ctx) const noexcept { diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 5d2824b6..f2a06bad 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -101,6 +101,18 @@ struct state_step_error_out_decision {}; struct state_step_callback_decision {}; struct state_step_failed_error_out_decision {}; struct state_step_failed_callback_decision {}; +struct state_predict_request_decision {}; +struct state_predict_allocate_slot {}; +struct state_predict_allocate_slot_decision {}; +struct state_predict_capture_memory {}; +struct state_predict_capture_memory_decision {}; +struct state_predict_begin {}; +struct state_predict_graph_runtime_decision {}; +struct state_predict_running_graph {}; +struct state_predict_graph_error_out_decision {}; +struct state_predict_graph_result_decision {}; +struct state_predict_error_out_decision {}; +struct state_predict_failed_error_out_decision {}; struct state_uninit_step_error_out_decision {}; struct state_uninit_step_callback_decision {}; struct state_uninit_voice_error_out_decision {}; @@ -120,6 +132,7 @@ struct model { using load_voice_run = event::load_voice_run; using prefill_prompt_run = event::prefill_personaplex_prompt_run; using prefill_voice_run = event::prefill_voice_run; + using predict_run = event::predict_run; using step_run = event::step_run; // clang-format off @@ -454,7 +467,84 @@ struct model { + sml::completion [ guard::guard_no_error_callback{} ] //------------------------------------------------------------------------------// - // Online step: validate audio-token frame, allocate the next + // Model-token prediction: memory and graph execution only. Delay + // tokenization and detokenization are owned by the caller's tokenizer. + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_predict_request_valid{} ] + / action::effect_allocate_step_slot{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_predict_blocked_by_voice_prompt{} ] + / action::effect_mark_voice_prompt_pending{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_predict_request_shape_invalid{} ] + / action::effect_mark_step_request_invalid{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_memory_accepted{} ] / action::effect_capture_memory{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_memory_rejected{} ] / action::effect_mark_memory_error{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_memory_accepted{} ] / action::effect_begin_predict{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_memory_rejected{} ] / action::effect_mark_memory_error{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_runtime_available{} ] / action::effect_run_predict_graph{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_runtime_unavailable{} ] + / action::effect_mark_graph_runtime_unavailable{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_has_graph_error_out{} ] / action::effect_store_predict_graph_error_out{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_no_graph_error_out{} ] + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_accepted{} ] / action::effect_publish_predict{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_rejected{} ] + / action::effect_mark_graph_runtime_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + + // Predictor-owned prompt cache handoff into the injected tokenizer. + , sml::state <= sml::state + + sml::event + [ guard::guard_capture_tokenizer_state_valid{} ] + / action::effect_capture_tokenizer_state{} + , sml::state <= sml::state + + sml::event + [ guard::guard_capture_tokenizer_state_invalid{} ] + / action::effect_reject_capture_tokenizer_state{} + + //------------------------------------------------------------------------------// + // Legacy online step: validate audio-token frame, allocate the next // Cortext-owned KV slot, capture memory, then enter the explicitly // modeled Moshi graph execution route. , sml::state <= sml::state @@ -576,6 +666,15 @@ struct model { //------------------------------------------------------------------------------// // Requests before initialization answer with explicit errors. + , sml::state <= sml::state + + sml::event [ guard::guard_has_error_out{} ] + / action::effect_mark_not_initialized_and_store{} + , sml::state <= sml::state + + sml::event [ guard::guard_no_error_out{} ] + / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_capture_tokenizer_state{} , sml::state <= sml::state + sml::event / action::effect_mark_not_initialized{} @@ -728,6 +827,18 @@ struct sm : public emel::sm { return accepted && ctx.err == action::detail_ns::to_error(error::none); } + bool process_event(const event::predict &ev) { + event::predict_ctx ctx{*memory_snapshot_}; + event::predict_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + + bool process_event(const event::capture_tokenizer_state &ev) { + const bool accepted = base_type::process_event(ev); + return accepted && ev.error_out == action::detail_ns::to_error(error::none); + } + bool process_event(const event::reset &ev) { event::reset_run runtime_ev{ev}; return base_type::process_event(runtime_ev); diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index f139b420..c48c520c 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -61,7 +61,43 @@ struct fake_predict { int32_t &text_token_out; emel::error::type *error_out = nullptr; emel::error::type *graph_error_out = nullptr; - bool *produced_out = nullptr; +}; + +struct fake_tokenizer_initialize { + int32_t &error_out; +}; + +struct fake_tokenize { + std::span audio_tokens = {}; + std::span model_tokens_out = {}; + int32_t &error_out; +}; + +struct fake_detokenize { + int32_t text_token = -1; + std::span audio_tokens = {}; + int32_t &text_token_out; + std::span audio_tokens_out = {}; + bool &produced_out; + int32_t &error_out; +}; + +struct fake_capture_tokenizer_state { + fake_capture_tokenizer_state(std::span cache_out_ref, + int64_t &offset_out_ref, + emel::error::type &error_out_ref) noexcept + : cache_out(cache_out_ref), offset_out(offset_out_ref), + error_out(error_out_ref) {} + + std::span cache_out = {}; + int64_t &offset_out; + emel::error::type &error_out; +}; + +struct fake_restore_tokenizer_state { + std::span cache = {}; + int64_t offset = 0; + int32_t &error_out; }; struct fake_decode { @@ -131,6 +167,44 @@ struct fake_runtime_actor { } }; +struct fake_tokenizer_actor { + int32_t initialize_calls = 0; + int32_t tokenize_calls = 0; + int32_t detokenize_calls = 0; + int32_t restore_calls = 0; + bool produce = true; + + bool process_event(const fake_tokenizer_initialize &request) noexcept { + ++initialize_calls; + request.error_out = 0; + return true; + } + + bool process_event(const fake_tokenize &request) noexcept { + ++tokenize_calls; + std::copy(request.audio_tokens.begin(), request.audio_tokens.end(), + request.model_tokens_out.begin()); + request.error_out = 0; + return true; + } + + bool process_event(const fake_detokenize &request) noexcept { + ++detokenize_calls; + std::copy(request.audio_tokens.begin(), request.audio_tokens.end(), + request.audio_tokens_out.begin()); + request.text_token_out = request.text_token; + request.produced_out = produce; + request.error_out = 0; + return true; + } + + bool process_event(const fake_restore_tokenizer_state &request) noexcept { + ++restore_calls; + request.error_out = 0; + return true; + } +}; + struct fake_predictor_actor { int32_t initialize_calls = 0; int32_t conditioning_initialize_calls = 0; @@ -153,7 +227,6 @@ struct fake_predictor_actor { emel::error::type predict_graph_error = 0; bool voice_complete = true; bool prompt_complete = true; - bool produce = true; bool process_event(const fake_initialize &request) noexcept { ++initialize_calls; @@ -192,9 +265,15 @@ struct fake_predictor_actor { request.text_token_out = 42; *request.error_out = predict_error; *request.graph_error_out = predict_graph_error; - *request.produced_out = produce; return predict_accepted; } + + bool process_event(const fake_capture_tokenizer_state &request) noexcept { + std::fill(request.cache_out.begin(), request.cache_out.end(), 0); + request.offset_out = 0; + request.error_out = 0; + return true; + } }; struct fake_dependencies { @@ -203,12 +282,18 @@ struct fake_dependencies { using prompt_begin_event = fake_prompt_begin; using prompt_condition_event = fake_prompt_condition; using encode_event = fake_encode; + using tokenizer_initialize_event = fake_tokenizer_initialize; + using tokenize_event = fake_tokenize; using predict_event = fake_predict; + using detokenize_event = fake_detokenize; + using capture_tokenizer_state_event = fake_capture_tokenizer_state; + using restore_tokenizer_state_event = fake_restore_tokenizer_state; using decode_event = fake_decode; emel::memory::streaming::sm &temporal_positions; emel::memory::streaming::sm &secondary_positions; fake_encoder_actor &encoder; + fake_tokenizer_actor &tokenizer; fake_decoder_actor &decoder; fake_runtime_actor &runtime; fake_predictor_actor &predictor; @@ -219,7 +304,11 @@ struct fake_dependencies { fake_initialize conditioning_initialize = {}; std::span silence_pcm = {}; std::span input_codes = {}; + std::span tokenize_input_codes = {}; + std::span model_codes = {}; + std::span predicted_codes = {}; std::span output_codes = {}; + std::span tokenizer_cache_snapshot = {}; int32_t frame_samples = 0; int32_t codebook_count = 0; }; @@ -227,12 +316,16 @@ struct fake_dependencies { struct fixture { std::array silence{}; std::array input_codes{}; + std::array model_codes{}; + std::array predicted_codes{}; std::array output_codes{}; + std::array tokenizer_cache_snapshot{}; emel::memory::streaming::sm temporal_positions{ emel::memory::streaming::dependencies{.capacity = 16}}; emel::memory::streaming::sm secondary_positions{ emel::memory::streaming::dependencies{.capacity = 16}}; fake_encoder_actor encoder{}; + fake_tokenizer_actor tokenizer{}; fake_decoder_actor decoder{}; fake_runtime_actor runtime{}; fake_predictor_actor predictor{}; @@ -245,12 +338,17 @@ struct fixture { .temporal_positions = temporal_positions, .secondary_positions = secondary_positions, .encoder = encoder, + .tokenizer = tokenizer, .decoder = decoder, .runtime = runtime, .predictor = predictor, .silence_pcm = std::span{silence}, .input_codes = std::span{input_codes}, + .tokenize_input_codes = std::span{input_codes}, + .model_codes = std::span{model_codes}, + .predicted_codes = std::span{predicted_codes}, .output_codes = std::span{output_codes}, + .tokenizer_cache_snapshot = std::span{tokenizer_cache_snapshot}, .frame_samples = frame_samples, .codebook_count = codebook_count, }, @@ -647,7 +745,7 @@ TEST_CASE("speech_generator_streams_pending_frames_and_reports_failures") { err}; SUBCASE("pending") { - test->predictor.produce = false; + test->tokenizer.produce = false; request.on_done = decltype(request.on_done)::from(&probe); @@ -748,7 +846,7 @@ TEST_CASE("speech_generator_flushes_pending_frames_and_reports_failures") { err}; SUBCASE("pending") { - test->predictor.produce = false; + test->tokenizer.produce = false; request.on_done = decltype(request.on_done)::from(&probe); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 6bdad5ee..2b387c77 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -24,6 +24,7 @@ #include "emel/speech/generator/sm.hpp" #include "emel/speech/predictor/moshi/any.hpp" #include "emel/speech/predictor/moshi/executor/any.hpp" +#include "emel/speech/tokenizer/moshi/any.hpp" namespace { @@ -31,6 +32,7 @@ namespace mimi = emel::speech::codec::mimi; namespace generator = emel::speech::generator; namespace predictor = emel::speech::predictor::moshi; namespace runtime = emel::speech::predictor::moshi::executor; +namespace tokenizer = emel::speech::tokenizer::moshi; struct runner_config { const char *mimi_path = nullptr; @@ -94,12 +96,19 @@ struct personaplex_dependencies { using prompt_begin_event = predictor::event::begin_personaplex_prompt; using prompt_condition_event = predictor::event::prefill_personaplex_prompt; using encode_event = mimi::event::encode_frame; - using predict_event = predictor::event::step; + using tokenizer_initialize_event = tokenizer::event::initialize; + using tokenize_event = tokenizer::event::tokenize; + using predict_event = predictor::event::predict; + using detokenize_event = tokenizer::event::detokenize; + using capture_tokenizer_state_event = + predictor::event::capture_tokenizer_state; + using restore_tokenizer_state_event = tokenizer::event::restore_cache; using decode_event = mimi::event::decode_frame; emel::memory::streaming::sm &temporal_positions; emel::memory::streaming::sm &secondary_positions; mimi::sm &encoder; + tokenizer::sm &tokenizer; mimi::sm &decoder; runtime::sm &runtime; predictor::sm &predictor; @@ -110,7 +119,11 @@ struct personaplex_dependencies { predictor::event::load_voice conditioning_initialize; std::span silence_pcm = {}; std::span input_codes = {}; + std::span tokenize_input_codes = {}; + std::span model_codes = {}; + std::span predicted_codes = {}; std::span output_codes = {}; + std::span tokenizer_cache_snapshot = {}; int32_t frame_samples = 0; int32_t codebook_count = 0; }; @@ -472,7 +485,20 @@ int main(int argc, char **argv) { std::vector output_pcm(config.target_output_frames * frame_samples, 0.0f); std::vector input_codes(static_cast(public_n_q), -1); + const int32_t model_codebook_count = lm_model.model->moshi_lm.n_q + 1; + const auto delay_begin = lm_model.model->moshi_lm.delays.begin(); + const auto delay_end = delay_begin + lm_model.model->moshi_lm.delay_count; + const int32_t maximum_delay = *std::max_element(delay_begin, delay_end); + const int32_t tokenizer_cache_rows = maximum_delay + 3; + std::vector model_codes(static_cast(model_codebook_count), + -1); + std::vector predicted_codes( + static_cast(lm_model.model->moshi_lm.dep_q), -1); std::vector output_codes(static_cast(public_n_q), -1); + std::vector tokenizer_storage( + static_cast(tokenizer_cache_rows * model_codebook_count), -2); + std::vector tokenizer_cache_snapshot( + static_cast(tokenizer_cache_rows * model_codebook_count), -2); emel::memory::streaming::sm temporal_positions{ emel::memory::streaming::dependencies{ @@ -509,6 +535,20 @@ int main(int argc, char **argv) { predictor::sm token_predictor{ emel::memory::hybrid::kv_binding{}, runtime::bind_graph_executor(prediction_runtime)}; + tokenizer::sm token_delay{tokenizer::dependencies{ + .delays = std::span{delay_begin, delay_end}, + .cache = std::span{tokenizer_storage}, + .codebooks = model_codebook_count, + .generated_audio_codebooks = lm_model.model->moshi_lm.dep_q, + .delayed_audio_codebooks = lm_model.model->moshi_lm.inference_dep_q, + .cache_rows = tokenizer_cache_rows, + .maximum_delay = maximum_delay, + .initial_delay_frames = 0, + .text_initial_token = lm_model.model->moshi_lm.text_card, + .audio_initial_token = lm_model.model->moshi_lm.card, + .token_zero = -1, + .token_ungenerated = -2, + }}; mimi::sm encoder{}; mimi::sm decoder{}; @@ -528,6 +568,7 @@ int main(int argc, char **argv) { .temporal_positions = temporal_positions, .secondary_positions = secondary_positions, .encoder = encoder, + .tokenizer = token_delay, .decoder = decoder, .runtime = prediction_runtime, .predictor = token_predictor, @@ -549,7 +590,11 @@ int main(int argc, char **argv) { predictor::event::load_voice{*voice_model.model}, .silence_pcm = std::span{pcm_frame}, .input_codes = std::span{input_codes}, + .tokenize_input_codes = std::span{input_codes}, + .model_codes = std::span{model_codes}, + .predicted_codes = std::span{predicted_codes}, .output_codes = std::span{output_codes}, + .tokenizer_cache_snapshot = std::span{tokenizer_cache_snapshot}, .frame_samples = frame_samples_i32, .codebook_count = public_n_q, }; @@ -583,7 +628,6 @@ int main(int argc, char **argv) { static_cast(session_err)); return 1; } - for (size_t frame_index = 0; frame_index < input_frames; ++frame_index) { std::fill(pcm_frame.begin(), pcm_frame.end(), 0.0f); const size_t begin = frame_index * frame_samples; @@ -603,7 +647,11 @@ int main(int argc, char **argv) { sample_count, produced, session_err}; - (void)session.process_event(frame); + if (!session.process_event(frame)) { + std::fprintf(stderr, "PersonaPlex stream frame=%zu failed err=%d\n", + frame_index, static_cast(session_err)); + return 1; + } std::fprintf(stderr, "EMEL_INPUT frame=%zu codes=", frame_index); for (int32_t index = 0; index < public_n_q; ++index) { std::fprintf(stderr, "%s%d", index == 0 ? "" : ",", @@ -635,7 +683,11 @@ int main(int argc, char **argv) { sample_count, complete, session_err}; - (void)session.process_event(frame); + if (!session.process_event(frame)) { + std::fprintf(stderr, "PersonaPlex flush frame=%zu failed err=%d\n", + frame_index, static_cast(session_err)); + return 1; + } std::fprintf(stderr, "EMEL_INPUT frame=%zu codes=", frame_index); for (int32_t codebook = 0; codebook < public_n_q; ++codebook) { std::fprintf(stderr, "%s%d", codebook == 0 ? "" : ",", From 778c2fe3fe61aec5350429c1df32aff54bb9da86 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 18:54:46 -0500 Subject: [PATCH 16/61] refactor: remove legacy moshi predictor step path --- src/emel/speech/predictor/moshi/actions.hpp | 216 --------- src/emel/speech/predictor/moshi/events.hpp | 55 --- src/emel/speech/predictor/moshi/guards.hpp | 157 ------ src/emel/speech/predictor/moshi/sm.hpp | 168 ------- .../predictor/moshi_lifecycle_tests.cpp | 459 +++--------------- 5 files changed, 71 insertions(+), 984 deletions(-) diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index 9a43b25b..d4604f89 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -602,25 +602,6 @@ struct effect_store_voice_remaining_out { } }; -struct effect_begin_step { - void operator()(const event::step_run &runtime_ev, - const context &ctx) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::none); - runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); - runtime_ev.ctx.graph_accepted = false; - runtime_ev.ctx.provided_input = false; - runtime_ev.ctx.produced = false; - runtime_ev.ctx.text_token = 0; - runtime_ev.ctx.generated_dep_q = ctx.lmgen.generated_dep_q; - runtime_ev.ctx.delayed_dep_q = ctx.lmgen.delayed_dep_q; - runtime_ev.ctx.needed_tokens = ctx.lmgen.needed_tokens; - std::fill(runtime_ev.ctx.input_sequence.begin(), - runtime_ev.ctx.input_sequence.end(), k_token_ungenerated); - std::fill(runtime_ev.ctx.audio_tokens.begin(), - runtime_ev.ctx.audio_tokens.end(), k_token_ungenerated); - } -}; - struct effect_begin_predict { void operator()(const event::predict_run &runtime_ev, const context &) const noexcept { @@ -688,68 +669,6 @@ template struct effect_reject_capture_tokenizer_state { } }; -struct effect_write_full_input { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - for (int32_t index = 0; index < ctx.lmgen.codebook_count; ++index) { - const int32_t row = detail::cache_position( - ctx.lmgen, ctx.lmgen.offset + ctx.lmgen.delays[index]); - detail::cache_at(ctx.lmgen, row, index) = - runtime_ev.request.audio_tokens[static_cast(index)]; - } - runtime_ev.ctx.provided_input = true; - } -}; - -struct effect_write_tail_input { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - const int32_t start = ctx.lmgen.delayed_dep_q + 1; - for (int32_t index = 0; index < ctx.lmgen.needed_tokens; ++index) { - const int32_t column = start + index; - const int32_t row = detail::cache_position( - ctx.lmgen, ctx.lmgen.offset + ctx.lmgen.delays[column]); - detail::cache_at(ctx.lmgen, row, column) = - runtime_ev.request.audio_tokens[static_cast(index)]; - } - } -}; - -struct effect_build_input_sequence { - void operator()(const event::step_run &runtime_ev, - const context &ctx) const noexcept { - const int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset); - for (int32_t index = 0; index < ctx.lmgen.codebook_count; ++index) { - const bool use_initial = ctx.lmgen.offset <= ctx.lmgen.delays[index]; - const int32_t initial_lane = static_cast(use_initial); - const int32_t cache_lane = static_cast(!use_initial); - runtime_ev.ctx.input_sequence[static_cast(index)] = - (initial_lane * ctx.lmgen.initial[index]) + - (cache_lane * detail::cache_at(ctx.lmgen, row, index)); - } - } -}; - -struct effect_run_graph_runtime { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); - event::graph_step graph_step{ - *ctx.session.model, - runtime_ev.ctx.memory_snapshot, - std::span{runtime_ev.ctx.input_sequence.data(), - static_cast(ctx.lmgen.codebook_count)}, - std::span{runtime_ev.ctx.audio_tokens.data(), - static_cast(ctx.lmgen.generated_dep_q)}, - runtime_ev.ctx.text_token, - }; - graph_step.sequence_id = ctx.session.sequence_id; - graph_step.error_out = &runtime_ev.ctx.graph_error; - runtime_ev.ctx.graph_accepted = - ctx.graph.dispatch_step(ctx.graph.executor, graph_step); - } -}; - struct effect_store_graph_error_out { template void operator()(const runtime_event_type &runtime_ev, @@ -759,117 +678,6 @@ struct effect_store_graph_error_out { } }; -struct effect_replace_audio_with_zero { - void operator()(const event::step_run &runtime_ev, - const context &) const noexcept { - for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { - runtime_ev.ctx.audio_tokens[static_cast(index)] = k_token_zero; - } - } -}; - -struct effect_apply_delay_mask { - void operator()(const event::step_run &runtime_ev, - const context &ctx) const noexcept { - for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { - const int32_t delay_index = index + 1; - const bool masked = (ctx.lmgen.delay_steps > 0) && - (ctx.lmgen.offset < (ctx.lmgen.delays[delay_index] + - ctx.lmgen.delay_steps)); - const int32_t zero_lane = static_cast(masked); - const int32_t current_lane = static_cast(!masked); - runtime_ev.ctx.audio_tokens[static_cast(index)] = - (zero_lane * k_token_zero) + - (current_lane * - runtime_ev.ctx.audio_tokens[static_cast(index)]); - } - } -}; - -struct effect_advance_offset { - void operator()(const event::step_run &, context &ctx) const noexcept { - ++ctx.lmgen.offset; - } -}; - -struct effect_apply_delay_mask_and_advance { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - effect_apply_delay_mask{}(runtime_ev, ctx); - effect_advance_offset{}(runtime_ev, ctx); - } -}; - -struct effect_write_generated { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - const int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset); - detail::cache_at(ctx.lmgen, row, 0) = runtime_ev.ctx.text_token; - for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { - detail::cache_at(ctx.lmgen, row, index + 1) = - runtime_ev.ctx.audio_tokens[static_cast(index)]; - } - } -}; - -struct effect_write_generated_missing { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - const int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset); - detail::cache_at(ctx.lmgen, row, 0) = runtime_ev.ctx.text_token; - for (int32_t index = 0; index < runtime_ev.ctx.generated_dep_q; ++index) { - const int32_t column = index + 1; - const int32_t current = detail::cache_at(ctx.lmgen, row, column); - const int32_t missing_lane = - static_cast(current == k_token_ungenerated); - const int32_t current_lane = static_cast(!missing_lane); - detail::cache_at(ctx.lmgen, row, column) = - (current_lane * current) + - (missing_lane * - runtime_ev.ctx.audio_tokens[static_cast(index)]); - } - } -}; - -struct effect_consume_skip { - void operator()(const event::step_run &, context &ctx) const noexcept { - --ctx.lmgen.skip; - } -}; - -struct effect_collect_delayed_output { - void operator()(const event::step_run &runtime_ev, - const context &ctx) const noexcept { - int32_t row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset - - ctx.lmgen.max_delay + - ctx.lmgen.delays[0]); - runtime_ev.request.text_token_out = detail::cache_at(ctx.lmgen, row, 0); - for (int32_t index = 0; index < runtime_ev.ctx.delayed_dep_q; ++index) { - runtime_ev.request.audio_tokens_out[static_cast(index)] = - runtime_ev.ctx.audio_tokens[static_cast(index)]; - } - for (int32_t index = 1; index <= runtime_ev.ctx.delayed_dep_q; ++index) { - row = detail::cache_position(ctx.lmgen, ctx.lmgen.offset - - ctx.lmgen.max_delay + - ctx.lmgen.delays[index]); - runtime_ev.request.audio_tokens_out[static_cast(index - 1)] = - detail::cache_at(ctx.lmgen, row, index); - } - } -}; - -struct effect_publish_output { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - runtime_ev.ctx.produced = true; - } -}; - -struct effect_publish_no_output { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - runtime_ev.ctx.produced = false; - } -}; - struct effect_reset_session { void operator()(const event::reset_run &, context &ctx) const noexcept { ctx.session = {}; @@ -885,12 +693,6 @@ template struct effect_store_error_out { } }; -struct effect_store_produced_out { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - *runtime_ev.request.produced_out = runtime_ev.ctx.produced; - } -}; - struct effect_emit_initialize_done { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { @@ -994,24 +796,6 @@ struct effect_emit_prefill_personaplex_prompt_error { } }; -struct effect_emit_step_done { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - runtime_ev.request.on_done(events::step_done{ - .request = &runtime_ev.request, - .produced = runtime_ev.ctx.produced, - }); - } -}; - -struct effect_emit_step_error { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - runtime_ev.request.on_error(events::step_error{ - .request = &runtime_ev.request, - .err = runtime_ev.ctx.err, - }); - } -}; - struct effect_mark_unexpected { template void operator()(const unexpected_event_type &ev, context &) const noexcept { diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index d7ceb840..6ab8f848 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -23,8 +23,6 @@ struct prefill_voice_done; struct prefill_voice_error; struct prefill_personaplex_prompt_done; struct prefill_personaplex_prompt_error; -struct step_done; -struct step_error; } // namespace emel::speech::predictor::moshi::events @@ -89,23 +87,6 @@ struct prefill_personaplex_prompt { on_error = {}; }; -struct step { - step(std::span audio_tokens_ref, - std::span audio_tokens_out_ref, - int32_t &text_token_out_ref) noexcept - : audio_tokens(audio_tokens_ref), audio_tokens_out(audio_tokens_out_ref), - text_token_out(text_token_out_ref) {} - - std::span audio_tokens = {}; - std::span audio_tokens_out = {}; - int32_t &text_token_out; - emel::error::type *error_out = nullptr; - emel::error::type *graph_error_out = nullptr; - bool *produced_out = nullptr; - emel::callback on_done = {}; - emel::callback on_error = {}; -}; - struct predict { predict(std::span model_tokens_ref, std::span audio_tokens_out_ref, @@ -212,27 +193,6 @@ struct prefill_personaplex_prompt_ctx { emel::memory::view::snapshot &memory_snapshot; }; -struct step_ctx { - explicit step_ctx(emel::memory::view::snapshot &memory_snapshot_ref) noexcept - : memory_snapshot(memory_snapshot_ref) {} - - emel::error::type err = emel::error::cast(error::none); - bool memory_accepted = false; - int32_t memory_error = static_cast(emel::error::cast(error::none)); - int32_t memory_block_count = 0; - bool graph_accepted = false; - emel::error::type graph_error = emel::error::cast(error::none); - bool provided_input = false; - bool produced = false; - int32_t text_token = 0; - int32_t generated_dep_q = 0; - int32_t delayed_dep_q = 0; - int32_t needed_tokens = 0; - std::array input_sequence = {}; - std::array audio_tokens = {}; - emel::memory::view::snapshot &memory_snapshot; -}; - struct predict_ctx { explicit predict_ctx( emel::memory::view::snapshot &memory_snapshot_ref) noexcept @@ -272,11 +232,6 @@ struct prefill_personaplex_prompt_run { prefill_personaplex_prompt_ctx &ctx; }; -struct step_run { - const step &request; - step_ctx &ctx; -}; - struct predict_run { const predict &request; predict_ctx &ctx; @@ -343,14 +298,4 @@ struct prefill_personaplex_prompt_error { emel::error::type err = emel::error::cast(error::none); }; -struct step_done { - const event::step *request = nullptr; - bool produced = false; -}; - -struct step_error { - const event::step *request = nullptr; - emel::error::type err = emel::error::cast(error::none); -}; - } // namespace emel::speech::predictor::moshi::events diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 69c4ca0d..cfd09db0 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -128,50 +128,6 @@ struct guard_memory_rejected { } }; -struct guard_step_request_valid { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - const bool input_full = runtime_ev.request.audio_tokens.size() == - static_cast(ctx.lmgen.codebook_count); - const bool input_tail = ctx.lmgen.needed_tokens > 0 && - runtime_ev.request.audio_tokens.size() >= - static_cast(ctx.lmgen.needed_tokens) && - runtime_ev.request.audio_tokens.size() != - static_cast(ctx.lmgen.codebook_count); - const bool input_optional = ctx.lmgen.needed_tokens == 0; - const bool voice_ready = - !ctx.voice.loaded || (ctx.voice.ready && ctx.voice.prompt_ready); - return ctx.session.model != nullptr && voice_ready && - runtime_ev.request.audio_tokens_out.data() != nullptr && - runtime_ev.request.audio_tokens_out.size() >= - static_cast(ctx.lmgen.delayed_dep_q) && - (input_full || input_tail || input_optional); - } -}; - -struct guard_step_request_invalid { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_step_request_valid{}(runtime_ev, ctx); - } -}; - -struct guard_step_blocked_by_voice_prompt { - bool operator()(const event::step_run &, - const action::context &ctx) const noexcept { - return ctx.session.model != nullptr && ctx.voice.loaded && - (!ctx.voice.ready || !ctx.voice.prompt_ready); - } -}; - -struct guard_step_request_shape_invalid { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_step_request_valid{}(runtime_ev, ctx) && - !guard_step_blocked_by_voice_prompt{}(runtime_ev, ctx); - } -}; - struct guard_predict_request_valid { bool operator()(const event::predict_run &runtime_ev, const action::context &ctx) const noexcept { @@ -476,33 +432,6 @@ struct guard_no_voice_remaining_out { } }; -struct guard_has_full_input { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return runtime_ev.request.audio_tokens.size() == - static_cast(ctx.lmgen.codebook_count); - } -}; - -struct guard_has_tail_input { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return ctx.lmgen.needed_tokens > 0 && - runtime_ev.request.audio_tokens.size() >= - static_cast(ctx.lmgen.needed_tokens) && - runtime_ev.request.audio_tokens.size() != - static_cast(ctx.lmgen.codebook_count); - } -}; - -struct guard_has_no_input_write { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_has_full_input{}(runtime_ev, ctx) && - !guard_has_tail_input{}(runtime_ev, ctx); - } -}; - struct guard_graph_runtime_available { template bool operator()(const runtime_event_type &, @@ -578,92 +507,6 @@ struct guard_no_graph_error_out { } }; -struct guard_replace_depformer_tokens { - bool operator()(const event::step_run &, - const action::context &ctx) const noexcept { - return ctx.lmgen.delay_steps > 0 && - ctx.lmgen.offset < ctx.lmgen.delay_steps; - } -}; - -struct guard_use_graph_audio_tokens { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_replace_depformer_tokens{}(runtime_ev, ctx); - } -}; - -struct guard_should_write_generated { - bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { - return !runtime_ev.ctx.provided_input; - } -}; - -struct guard_provided_input { - bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.ctx.provided_input; - } -}; - -struct guard_skip_pending { - bool operator()(const event::step_run &, - const action::context &ctx) const noexcept { - return ctx.lmgen.skip > 0; - } -}; - -struct guard_before_delay { - bool operator()(const event::step_run &, - const action::context &ctx) const noexcept { - return ctx.lmgen.offset <= ctx.lmgen.max_delay; - } -}; - -struct guard_past_delay { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_skip_pending{}(runtime_ev, ctx) && - !guard_before_delay{}(runtime_ev, ctx); - } -}; - -struct guard_output_has_ungenerated { - bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { - bool has_ungenerated = false; - for (int32_t index = 0; index < runtime_ev.ctx.delayed_dep_q; ++index) { - if (runtime_ev.request.audio_tokens_out[static_cast(index)] == - action::k_token_zero) { - has_ungenerated = true; - } - } - return has_ungenerated; - } -}; - -struct guard_output_complete { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_output_has_ungenerated{}(runtime_ev, ctx); - } -}; - -struct guard_has_produced_out { - bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { - return runtime_ev.request.produced_out != nullptr; - } -}; - -struct guard_no_produced_out { - bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_has_produced_out{}(runtime_ev, ctx); - } -}; - template struct guard_has_error_out { bool operator()(const runtime_event_type &runtime_ev, const action::context &) const noexcept { diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index f2a06bad..d40e0a7a 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -78,29 +78,6 @@ struct state_prefill_personaplex_prompt_error_out_decision {}; struct state_prefill_personaplex_prompt_callback_decision {}; struct state_prefill_personaplex_prompt_failed_error_out_decision {}; struct state_prefill_personaplex_prompt_failed_callback_decision {}; -struct state_step_request_decision {}; -struct state_allocate_step_slot {}; -struct state_allocate_step_slot_decision {}; -struct state_capture_memory {}; -struct state_capture_memory_decision {}; -struct state_step_begin {}; -struct state_input_write_decision {}; -struct state_build_input_sequence {}; -struct state_graph_runtime_decision {}; -struct state_running_graph {}; -struct state_graph_error_out_decision {}; -struct state_graph_result_decision {}; -struct state_depformer_decision {}; -struct state_apply_delay_mask {}; -struct state_write_generated_decision {}; -struct state_skip_delay_decision {}; -struct state_collect_output {}; -struct state_output_decision {}; -struct state_step_produced_out_decision {}; -struct state_step_error_out_decision {}; -struct state_step_callback_decision {}; -struct state_step_failed_error_out_decision {}; -struct state_step_failed_callback_decision {}; struct state_predict_request_decision {}; struct state_predict_allocate_slot {}; struct state_predict_allocate_slot_decision {}; @@ -113,8 +90,6 @@ struct state_predict_graph_error_out_decision {}; struct state_predict_graph_result_decision {}; struct state_predict_error_out_decision {}; struct state_predict_failed_error_out_decision {}; -struct state_uninit_step_error_out_decision {}; -struct state_uninit_step_callback_decision {}; struct state_uninit_voice_error_out_decision {}; struct state_uninit_voice_callback_decision {}; struct state_uninit_prefill_voice_error_out_decision {}; @@ -133,7 +108,6 @@ struct model { using prefill_prompt_run = event::prefill_personaplex_prompt_run; using prefill_voice_run = event::prefill_voice_run; using predict_run = event::predict_run; - using step_run = event::step_run; // clang-format off return sml::make_transition_table( @@ -543,127 +517,6 @@ struct model { [ guard::guard_capture_tokenizer_state_invalid{} ] / action::effect_reject_capture_tokenizer_state{} - //------------------------------------------------------------------------------// - // Legacy online step: validate audio-token frame, allocate the next - // Cortext-owned KV slot, capture memory, then enter the explicitly - // modeled Moshi graph execution route. - , sml::state <= sml::state - + sml::event - , sml::state <= sml::state - + sml::completion [ guard::guard_step_request_valid{} ] - / action::effect_allocate_step_slot{} - , sml::state <= sml::state - + sml::completion [ guard::guard_step_blocked_by_voice_prompt{} ] - / action::effect_mark_voice_prompt_pending{} - , sml::state <= sml::state - + sml::completion [ guard::guard_step_request_shape_invalid{} ] - / action::effect_mark_step_request_invalid{} - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion [ guard::guard_memory_accepted{} ] - / action::effect_capture_memory{} - , sml::state <= sml::state - + sml::completion [ guard::guard_memory_rejected{} ] - / action::effect_mark_memory_error{} - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion [ guard::guard_memory_accepted{} ] - / action::effect_begin_step{} - , sml::state <= sml::state - + sml::completion [ guard::guard_memory_rejected{} ] - / action::effect_mark_memory_error{} - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion [ guard::guard_has_full_input{} ] - / action::effect_write_full_input{} - , sml::state <= sml::state - + sml::completion [ guard::guard_has_tail_input{} ] - / action::effect_write_tail_input{} - , sml::state <= sml::state - + sml::completion [ guard::guard_has_no_input_write{} ] - , sml::state <= sml::state - + sml::completion - / action::effect_build_input_sequence{} - , sml::state <= sml::state - + sml::completion [ guard::guard_graph_runtime_available{} ] - / action::effect_run_graph_runtime{} - , sml::state <= sml::state - + sml::completion [ guard::guard_graph_runtime_unavailable{} ] - / action::effect_mark_graph_runtime_unavailable{} - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion [ guard::guard_has_graph_error_out{} ] - / action::effect_store_graph_error_out{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_graph_error_out{} ] - , sml::state <= sml::state - + sml::completion [ guard::guard_graph_step_accepted{} ] - , sml::state <= sml::state - + sml::completion [ guard::guard_graph_step_rejected{} ] - / action::effect_mark_graph_runtime_error{} - , sml::state <= sml::state - + sml::completion [ guard::guard_replace_depformer_tokens{} ] - / action::effect_replace_audio_with_zero{} - , sml::state <= sml::state - + sml::completion [ guard::guard_use_graph_audio_tokens{} ] - , sml::state <= sml::state - + sml::completion - / action::effect_apply_delay_mask_and_advance{} - , sml::state <= sml::state - + sml::completion [ guard::guard_should_write_generated{} ] - / action::effect_write_generated{} - , sml::state <= sml::state - + sml::completion [ guard::guard_provided_input{} ] - / action::effect_write_generated_missing{} - , sml::state <= sml::state - + sml::completion [ guard::guard_skip_pending{} ] - / action::effect_consume_skip{} - , sml::state <= sml::state - + sml::completion [ guard::guard_before_delay{} ] - / action::effect_publish_no_output{} - , sml::state <= sml::state - + sml::completion [ guard::guard_past_delay{} ] - / action::effect_collect_delayed_output{} - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion [ guard::guard_output_has_ungenerated{} ] - / action::effect_publish_no_output{} - , sml::state <= sml::state - + sml::completion [ guard::guard_output_complete{} ] - / action::effect_publish_output{} - - , sml::state <= sml::state - + sml::completion [ guard::guard_has_produced_out{} ] - / action::effect_store_produced_out{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_produced_out{} ] - - , sml::state <= sml::state - + sml::completion [ guard::guard_has_error_out{} ] - / action::effect_store_error_out{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_error_out{} ] - , sml::state <= sml::state - + sml::completion [ guard::guard_has_error_out{} ] - / action::effect_store_error_out{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_error_out{} ] - , sml::state <= sml::state - + sml::completion [ guard::guard_has_done_callback{} ] - / action::effect_emit_step_done{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_done_callback{} ] - , sml::state <= sml::state - + sml::completion [ guard::guard_has_error_callback{} ] - / action::effect_emit_step_error{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_error_callback{} ] - //------------------------------------------------------------------------------// // Requests before initialization answer with explicit errors. , sml::state <= sml::state @@ -675,20 +528,6 @@ struct model { , sml::state <= sml::state + sml::event / action::effect_reject_capture_tokenizer_state{} - , sml::state <= sml::state - + sml::event - / action::effect_mark_not_initialized{} - , sml::state <= sml::state - + sml::completion [ guard::guard_has_error_out{} ] - / action::effect_store_error_out{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_error_out{} ] - , sml::state <= sml::state - + sml::completion [ guard::guard_has_error_callback{} ] - / action::effect_emit_step_error{} - , sml::state <= sml::state - + sml::completion [ guard::guard_no_error_callback{} ] - , sml::state <= sml::state + sml::event / action::effect_mark_not_initialized{} @@ -820,13 +659,6 @@ struct sm : public emel::sm { return accepted && ctx.err == action::detail_ns::to_error(error::none); } - bool process_event(const event::step &ev) { - event::step_ctx ctx{*memory_snapshot_}; - event::step_run runtime_ev{ev, ctx}; - const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); - } - bool process_event(const event::predict &ev) { event::predict_ctx ctx{*memory_snapshot_}; event::predict_run runtime_ev{ev, ctx}; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 2d7ae32f..02cc4be2 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -13,7 +12,6 @@ #include "../../memory/recording_kv_actor.hpp" #include "emel/memory/streaming/sm.hpp" #include "emel/model/moshi/detail.hpp" -#include "emel/speech/codec/mimi/any.hpp" #include "emel/speech/predictor/moshi/any.hpp" #include "emel/speech/predictor/moshi/executor/any.hpp" #include "moshi_fixture.hpp" @@ -23,7 +21,6 @@ namespace { namespace moshi = emel::speech::predictor::moshi; namespace moshi_executor = emel::speech::predictor::moshi::executor; namespace memory_streaming = emel::memory::streaming; -namespace mimi = emel::speech::codec::mimi; namespace model_moshi = emel::model::moshi::detail; using emel::speech::predictor::moshi::test::load_fixture_or_skip; using emel::speech::predictor::moshi::test::read_binary_file; @@ -32,25 +29,6 @@ using emel::speech::predictor::moshi::test::repo_root; inline constexpr emel::error::type k_no_error = emel::error::cast(moshi::error::none); -int32_t g_mimi_frame_samples = 0; -int32_t g_mimi_n_q = 0; - -void on_mimi_initialized(const mimi::events::initialize_done &done) { - g_mimi_frame_samples = done.frame_samples; - g_mimi_n_q = done.n_q; -} - -std::vector deterministic_pcm(const int32_t frame_samples) { - std::vector pcm(static_cast(frame_samples), 0.0f); - for (int32_t index = 0; index < frame_samples; ++index) { - const float carrier = static_cast((index % 109) - 54) / 54.0f; - const float envelope = - 0.35f + 0.65f * static_cast((index / 160) % 2); - pcm[static_cast(index)] = 0.08f * envelope * carrier; - } - return pcm; -} - struct recording_graph_executor { int32_t call_count = 0; int32_t external_embedding_count = 0; @@ -167,19 +145,6 @@ struct moshi_callback_probe { err = error.err; } - void on_generator_step_done(const moshi::events::step_done &done) noexcept { - ++done_count; - request = done.request; - produced = done.produced; - } - - void - on_generator_step_error(const moshi::events::step_error &error) noexcept { - ++error_count; - request = error.request; - err = error.err; - } - void on_executor_initialize_done( const moshi_executor::events::initialize_done &done) noexcept { ++done_count; @@ -313,18 +278,18 @@ void initialize_streaming_position(memory_streaming::sm &position) { } // namespace -TEST_CASE("speech_moshi_generator_rejects_step_before_initialize") { +TEST_CASE("speech_moshi_predictor_rejects_predict_before_initialize") { moshi::sm generator{}; std::array input = {0, 0, 0, 0}; std::array output = {}; int32_t text_token = -1; emel::error::type err = k_no_error; - moshi::event::step step{std::span{input}, - std::span{output}, text_token}; - step.error_out = &err; + moshi::event::predict predict{std::span{input}, + std::span{output}, text_token}; + predict.error_out = &err; - CHECK_FALSE(generator.process_event(step)); + CHECK_FALSE(generator.process_event(predict)); CHECK(err == emel::error::cast(moshi::error::not_initialized)); } @@ -395,36 +360,6 @@ TEST_CASE("speech_moshi_generator_personaplex_uses_model_inference_codebooks") { CHECK(ctx.lmgen.delayed_dep_q == model->moshi_lm.inference_dep_q); CHECK(ctx.lmgen.needed_tokens == 8); CHECK(ctx.lmgen.cache_row_count == 4); - - auto snapshot = std::make_unique(); - moshi::event::step_ctx step_ctx{*snapshot}; - std::array prompt_tail = {}; - std::array output = {}; - int32_t text_token = -1; - moshi::event::step step{std::span{prompt_tail}, - std::span{output}, text_token}; - moshi::event::step_run step_run{step, step_ctx}; - - CHECK(moshi::guard::guard_step_request_valid{}(step_run, ctx)); - - ctx.lmgen.offset = 5; - step_ctx.generated_dep_q = ctx.lmgen.generated_dep_q; - step_ctx.delayed_dep_q = ctx.lmgen.delayed_dep_q; - for (int32_t row = 0; row < ctx.lmgen.cache_row_count; ++row) { - for (int32_t column = 0; column < ctx.lmgen.codebook_count; ++column) { - moshi::detail::cache_at(ctx.lmgen, row, column) = column * 10 + row; - } - } - for (int32_t index = 0; index < ctx.lmgen.generated_dep_q; ++index) { - step_ctx.audio_tokens[static_cast(index)] = 1000 + index; - } - - moshi::action::effect_collect_delayed_output{}(step_run, ctx); - - CHECK(text_token == 0); - for (int32_t index = 0; index < ctx.lmgen.delayed_dep_q; ++index) { - CHECK(output[static_cast(index)] == (index + 1) * 10 + 1); - } } TEST_CASE( @@ -456,16 +391,17 @@ TEST_CASE( CHECK(err == k_no_error); std::array output = {}; + std::array model_tokens = {}; int32_t text_token = -1; - bool produced = true; - moshi::event::step blocked_step{ - std::span{}, + moshi::event::predict blocked_predict{ + std::span{ + model_tokens.data(), + static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; - blocked_step.error_out = &err; - blocked_step.produced_out = &produced; - CHECK_FALSE(generator.process_event(blocked_step)); + blocked_predict.error_out = &err; + CHECK_FALSE(generator.process_event(blocked_predict)); CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); for (int32_t index = 0; index < prompt_frames; ++index) { @@ -572,17 +508,15 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" std::array output = {}; std::fill(input.begin(), input.end(), 0); int32_t text_token = -1; - bool produced = true; err = k_no_error; - moshi::event::step blocked_step{ - std::span{input.data(), - static_cast(needed_tokens)}, + moshi::event::predict blocked_predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; - blocked_step.error_out = &err; - blocked_step.produced_out = &produced; - CHECK_FALSE(generator.process_event(blocked_step)); + blocked_predict.error_out = &err; + CHECK_FALSE(generator.process_event(blocked_predict)); CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); err = k_no_error; @@ -623,19 +557,17 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" CHECK(kv.capture_view_count >= prompt_frames + 4); text_token = -1; - produced = true; err = k_no_error; emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); - moshi::event::step first_step{ - std::span{input.data(), - static_cast(needed_tokens)}, + moshi::event::predict first_predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; - first_step.error_out = &err; - first_step.graph_error_out = &graph_err; - first_step.produced_out = &produced; - REQUIRE(generator.process_event(first_step)); + first_predict.error_out = &err; + first_predict.graph_error_out = &graph_err; + REQUIRE(generator.process_event(first_predict)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); CHECK(graph.call_count == prompt_frames + 5); @@ -692,20 +624,18 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" std::array output = {}; std::fill(input.begin(), input.end(), 0); int32_t text_token = -1; - bool produced = false; emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); - moshi::event::step step{ - std::span{input.data(), - static_cast(needed_tokens)}, + moshi::event::predict predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; - step.error_out = &err; - step.graph_error_out = &graph_err; - step.produced_out = &produced; + predict.error_out = &err; + predict.graph_error_out = &graph_err; err = k_no_error; - CHECK_FALSE(generator.process_event(step)); + CHECK_FALSE(generator.process_event(predict)); CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); const int32_t personaplex_prompt_frames = @@ -734,13 +664,13 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" err = k_no_error; graph_err = emel::error::cast(moshi::error::graph_runtime); - REQUIRE(generator.process_event(step)); + REQUIRE(generator.process_event(predict)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); CHECK(graph.call_count == prompt_frames + personaplex_prompt_frames + 1); } -TEST_CASE("speech_moshi_generator_step_uses_memory_then_reports_missing_graph_" +TEST_CASE("speech_moshi_predictor_uses_memory_then_reports_missing_graph_" "runtime") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { @@ -754,15 +684,19 @@ TEST_CASE("speech_moshi_generator_step_uses_memory_then_reports_missing_graph_" init.error_out = &err; REQUIRE(generator.process_event(init)); - std::array input = {0, 1, 2, 3}; - std::array output = {}; + std::array input = {}; + std::array output = {}; int32_t text_token = -1; err = k_no_error; - moshi::event::step step{std::span{input}, - std::span{output}, text_token}; - step.error_out = &err; + moshi::event::predict predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + predict.error_out = &err; - CHECK_FALSE(generator.process_event(step)); + CHECK_FALSE(generator.process_event(predict)); CHECK(err == emel::error::cast(moshi::error::graph_runtime_unavailable)); CHECK(kv.allocate_slots_count == 1); CHECK(kv.capture_view_count == 1); @@ -1063,7 +997,8 @@ TEST_CASE("speech_moshi_generator_graph_outputs_use_explicit_transitions") { std::string::npos); CHECK(actions_source.find("effect_store_graph_debug_phase_out") == std::string::npos); - CHECK(sm_source.find("state_graph_error_out_decision") != std::string::npos); + CHECK(sm_source.find("state_predict_graph_error_out_decision") != + std::string::npos); CHECK(sm_source.find("state_graph_debug_phase_out_decision") == std::string::npos); } @@ -1084,31 +1019,32 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { CHECK(generator_ctx.lmgen.delayed_dep_q == fixture.model->moshi_lm.dep_q); auto generator_snapshot = std::make_unique(); - moshi::event::step_ctx generator_step_ctx{*generator_snapshot}; + moshi::event::predict_ctx generator_predict_ctx{*generator_snapshot}; std::array generator_input = {}; std::array generator_output = {}; int32_t generator_text = -1; - moshi::event::step generator_step{ + moshi::event::predict generator_predict{ std::span{generator_input.data(), 1}, std::span{generator_output.data(), 1}, generator_text}; - moshi::event::step_run generator_step_run{generator_step, generator_step_ctx}; - moshi::action::effect_mark_memory_error{}( - generator_step_run, generator_ctx); - CHECK(generator_step_ctx.err == emel::error::cast(moshi::error::memory)); - moshi::action::effect_mark_step_request_invalid{}(generator_step_run, + moshi::event::predict_run generator_predict_run{generator_predict, + generator_predict_ctx}; + moshi::action::effect_mark_memory_error{}( + generator_predict_run, generator_ctx); + CHECK(generator_predict_ctx.err == emel::error::cast(moshi::error::memory)); + moshi::action::effect_mark_step_request_invalid{}(generator_predict_run, generator_ctx); - CHECK(generator_step_ctx.err == + CHECK(generator_predict_ctx.err == emel::error::cast(moshi::error::request_shape)); - moshi::action::effect_mark_voice_contract_error{}( - generator_step_run, generator_ctx); - CHECK(generator_step_ctx.err == + moshi::action::effect_mark_voice_contract_error{}( + generator_predict_run, generator_ctx); + CHECK(generator_predict_ctx.err == emel::error::cast(moshi::error::voice_contract)); - moshi::action::effect_mark_personaplex_prompt_error{}( - generator_step_run, generator_ctx); - CHECK(generator_step_ctx.err == + moshi::action::effect_mark_personaplex_prompt_error< + moshi::event::predict_run>{}(generator_predict_run, generator_ctx); + CHECK(generator_predict_ctx.err == emel::error::cast(moshi::error::personaplex_prompt)); - CHECK( - moshi::guard::guard_memory_rejected{}(generator_step_run, generator_ctx)); + CHECK(moshi::guard::guard_memory_rejected{}(generator_predict_run, + generator_ctx)); moshi::event::begin_personaplex_prompt begin_prompt{}; moshi::event::begin_personaplex_prompt_ctx begin_prompt_ctx{}; @@ -1283,36 +1219,6 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { CHECK(callback_probe.err == emel::error::cast(moshi::error::graph_runtime_unavailable)); - bool produced = false; - emel::error::type generator_err = k_no_error; - generator_step.produced_out = &produced; - generator_step.error_out = &generator_err; - generator_step.on_done = - emel::callback::from< - moshi_callback_probe, &moshi_callback_probe::on_generator_step_done>( - &callback_probe); - generator_step.on_error = - emel::callback::from< - moshi_callback_probe, &moshi_callback_probe::on_generator_step_error>( - &callback_probe); - generator_step_ctx.produced = true; - generator_step_ctx.err = emel::error::cast(moshi::error::request_shape); - moshi::action::effect_store_produced_out{}(generator_step_run, generator_ctx); - moshi::action::effect_store_error_out{}( - generator_step_run, generator_ctx); - CHECK(produced); - CHECK(generator_err == emel::error::cast(moshi::error::request_shape)); - moshi::action::effect_emit_step_done{}(generator_step_run, generator_ctx); - CHECK(callback_probe.produced); - CHECK(callback_probe.request == &generator_step); - moshi::action::effect_emit_step_error{}(generator_step_run, generator_ctx); - CHECK(callback_probe.err == emel::error::cast(moshi::error::request_shape)); - moshi::action::effect_mark_unexpected_and_store{}(generator_step_run, - generator_ctx); - CHECK(generator_step_ctx.err == - emel::error::cast(moshi::error::unexpected_event)); - CHECK(generator_err == emel::error::cast(moshi::error::unexpected_event)); - const auto &lm = fixture.model->moshi_lm; emel::memory::view::snapshot snapshot{}; snapshot.max_sequences = 4; @@ -1909,171 +1815,8 @@ TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { second_output.begin())); } -TEST_CASE("speech_moshi_e2e_encodes_audio_generates_tokens_and_decodes_audio") { - auto codec_fixture = load_fixture_or_skip("mimi-tiny.gguf"); - auto lm_fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); - if (codec_fixture.model == nullptr || lm_fixture.model == nullptr) { - return; - } - - std::vector prepared( - mimi::prepared_arena_floats(*codec_fixture.model)); - std::vector state(mimi::state_arena_floats(*codec_fixture.model)); - std::vector workspace( - mimi::workspace_arena_floats(*codec_fixture.model)); - std::vector frame(mimi::frame_arena_floats(*codec_fixture.model)); - mimi::sm codec{}; - emel::error::type codec_err = emel::error::cast(mimi::error::none); - g_mimi_frame_samples = 0; - g_mimi_n_q = 0; - mimi::event::initialize codec_init{ - *codec_fixture.model, std::span{prepared}, std::span{state}, - std::span{workspace}, std::span{frame}}; - codec_init.error_out = &codec_err; - codec_init.on_done = emel::callback::from<&on_mimi_initialized>(); - REQUIRE(codec.process_event(codec_init)); - REQUIRE(codec_err == emel::error::cast(mimi::error::none)); - REQUIRE(g_mimi_frame_samples > 0); - REQUIRE(codec_fixture.model->mimi.card == lm_fixture.model->moshi_lm.card); - const int32_t public_n_q = lm_fixture.model->moshi_lm.inference_dep_q; - REQUIRE(public_n_q > 0); - REQUIRE(public_n_q <= lm_fixture.model->moshi_lm.n_q); - REQUIRE(g_mimi_n_q == public_n_q); - const int32_t needed_tokens = - (lm_fixture.model->moshi_lm.n_q + 1) - public_n_q - 1; - REQUIRE(needed_tokens > 0); - - const auto pcm = deterministic_pcm(g_mimi_frame_samples); - std::vector encoded_codes(static_cast(g_mimi_n_q), -1); - mimi::event::encode_frame encode{std::span{pcm}, - std::span{encoded_codes}}; - encode.error_out = &codec_err; - REQUIRE(codec.process_event(encode)); - REQUIRE(codec_err == emel::error::cast(mimi::error::none)); - for (const int32_t code : encoded_codes) { - REQUIRE(code >= 0); - REQUIRE(code < lm_fixture.model->moshi_lm.card); - } - - temporal_kv_probe temporal_probe{}; - depformer_kv_probe depformer_probe{}; - const auto temporal_kv = moshi_executor::bind_temporal_kv_cache( - &temporal_probe, temporal_kv_probe_bind); - const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( - &depformer_probe, depformer_kv_probe_bind); - memory_streaming::sm temporal_positions{memory_streaming::dependencies{ - .capacity = lm_fixture.model->moshi_lm.context}}; - memory_streaming::sm depformer_positions{memory_streaming::dependencies{ - .capacity = lm_fixture.model->moshi_lm.depformer_context}}; - initialize_streaming_position(temporal_positions); - initialize_streaming_position(depformer_positions); - moshi_executor::sm executor{moshi_executor::bind_kv_caches( - temporal_kv, depformer_kv, temporal_positions, depformer_positions)}; - emel::error::type executor_err = - emel::error::cast(moshi_executor::error::none); - moshi_executor::event::initialize executor_init{*lm_fixture.model}; - executor_init.error_out = &executor_err; - REQUIRE(executor.process_event(executor_init)); - REQUIRE(executor_err == emel::error::cast(moshi_executor::error::none)); - - moshi::sm generator{emel::memory::hybrid::kv_binding{}, - moshi_executor::bind_graph_executor(executor)}; - emel::error::type generator_err = k_no_error; - moshi::event::initialize generator_init{*lm_fixture.model}; - generator_init.error_out = &generator_err; - generator_init.max_blocks = 16; - generator_init.block_tokens = 4; - REQUIRE(generator.process_event(generator_init)); - REQUIRE(generator_err == k_no_error); - - std::array generated_codes = {}; - generated_codes.fill(-1); - std::array tail_input = {}; - tail_input.fill(-1); - REQUIRE(needed_tokens == public_n_q); - for (int32_t index = 0; index < needed_tokens; ++index) { - tail_input[static_cast(index)] = - encoded_codes[static_cast(index)]; - } - int32_t text_token = -1; - bool produced = false; - emel::error::type graph_err = emel::error::cast(moshi::error::none); - - moshi::event::step seed_step{ - std::span{tail_input.data(), - static_cast(needed_tokens)}, - std::span{generated_codes.data(), - static_cast(public_n_q)}, - text_token}; - seed_step.error_out = &generator_err; - seed_step.graph_error_out = &graph_err; - seed_step.produced_out = &produced; - REQUIRE(generator.process_event(seed_step)); - REQUIRE(generator_err == k_no_error); - REQUIRE(graph_err == k_no_error); - CHECK_FALSE(produced); - - int32_t generation_attempts = 0; - for (int32_t attempt = 0; attempt < 5; ++attempt) { - generated_codes.fill(-1); - text_token = -1; - produced = false; - graph_err = emel::error::cast(moshi::error::none); - moshi::event::step generate_step{ - std::span{tail_input.data(), - static_cast(needed_tokens)}, - std::span{generated_codes.data(), - static_cast(public_n_q)}, - text_token}; - generate_step.error_out = &generator_err; - generate_step.graph_error_out = &graph_err; - generate_step.produced_out = &produced; - CAPTURE(attempt); - CAPTURE(generator_err); - CAPTURE(graph_err); - REQUIRE(generator.process_event(generate_step)); - REQUIRE(generator_err == k_no_error); - REQUIRE(graph_err == k_no_error); - ++generation_attempts; - if (produced && generation_attempts >= 2) { - break; - } - } - - REQUIRE(produced); - REQUIRE(generation_attempts >= 2); - REQUIRE(temporal_probe.call_count >= 3); - REQUIRE(depformer_probe.call_count >= 3); - REQUIRE(text_token >= 0); - REQUIRE(text_token < lm_fixture.model->moshi_lm.text_card); - for (int32_t index = 0; index < public_n_q; ++index) { - const int32_t code = generated_codes[static_cast(index)]; - REQUIRE(code >= 0); - REQUIRE(code < codec_fixture.model->mimi.card); - } - - std::vector decoded(static_cast(g_mimi_frame_samples), 0.0f); - mimi::event::decode_frame decode{ - std::span{generated_codes.data(), - static_cast(public_n_q)}, - std::span{decoded}}; - decode.error_out = &codec_err; - REQUIRE(codec.process_event(decode)); - REQUIRE(codec_err == emel::error::cast(mimi::error::none)); - - bool all_finite = true; - bool has_energy = false; - for (const float sample : decoded) { - all_finite = all_finite && std::isfinite(sample); - has_energy = has_energy || std::abs(sample) > 1.0e-8f; - } - CHECK(all_finite); - CHECK(has_energy); -} - TEST_CASE( - "speech_moshi_generator_uses_emel_executor_binding_without_fake_tokens") { + "speech_moshi_predictor_uses_emel_executor_binding_without_fake_tokens") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { return; @@ -2094,82 +1837,22 @@ TEST_CASE( init.error_out = &err; REQUIRE(generator.process_event(init)); - std::array input = {0, 1, 2, 3}; - std::array output = {}; + std::array input = {}; + std::array output = {}; output.fill(-1); int32_t text_token = -1; - moshi::event::step step{std::span{input}, - std::span{output}, text_token}; - step.error_out = &err; + moshi::event::predict predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + predict.error_out = &err; - CHECK_FALSE(generator.process_event(step)); + CHECK_FALSE(generator.process_event(predict)); CHECK(err == emel::error::cast(moshi::error::graph_runtime)); CHECK(kv.allocate_slots_count == 1); CHECK(kv.capture_view_count == 1); CHECK(text_token == -1); CHECK(output[0] == -1); } - -TEST_CASE("speech_moshi_generator_runs_injected_graph_through_delay_cache") { - auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); - if (fixture.model == nullptr) { - return; - } - - emel::memory::test::recording_kv_actor kv{}; - recording_graph_executor graph{}; - auto graph_binding = - moshi::action::bind_graph_executor(&graph, dispatch_recording_graph); - moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv), graph_binding}; - emel::error::type err = k_no_error; - moshi::event::initialize init{*fixture.model}; - init.error_out = &err; - REQUIRE(generator.process_event(init)); - - std::array input = {0, 1, 2, 3}; - std::array output = {}; - output.fill(-1); - const size_t public_n_q = - static_cast(fixture.model->moshi_lm.inference_dep_q); - REQUIRE(public_n_q < output.size()); - int32_t text_token = -1; - bool produced = true; - emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); - - moshi::event::step first{std::span{input}, - std::span{output.data(), public_n_q}, - text_token}; - first.error_out = &err; - first.produced_out = &produced; - first.graph_error_out = &graph_err; - REQUIRE(generator.process_event(first)); - CHECK(err == k_no_error); - CHECK(graph_err == k_no_error); - CHECK_FALSE(produced); - CHECK(graph.call_count == 1); - CHECK(kv.allocate_slots_count == 1); - CHECK(kv.capture_view_count == 1); - CHECK(graph.first_sequence_length == 1); - CHECK(graph.first_input[0] == fixture.model->moshi_lm.text_card); - CHECK(graph.first_input[1] == fixture.model->moshi_lm.card); - - produced = false; - graph_err = emel::error::cast(moshi::error::graph_runtime); - moshi::event::step second{std::span{input}, - std::span{output.data(), public_n_q}, - text_token}; - second.error_out = &err; - second.produced_out = &produced; - second.graph_error_out = &graph_err; - REQUIRE(generator.process_event(second)); - CHECK(err == k_no_error); - CHECK(graph_err == k_no_error); - CHECK(produced); - CHECK(graph.call_count == 2); - CHECK(text_token == 101); - CHECK(output[0] == 1010); - CHECK(output[public_n_q] == -1); - CHECK(kv.allocate_slots_count == 2); - CHECK(kv.capture_view_count == 2); - CHECK(graph.second_sequence_length == 2); -} From c612cadbca6e408ae07658ccd67daa45525dfbad Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 19:12:03 -0500 Subject: [PATCH 17/61] refactor: split duplex prediction and sampling phases --- src/emel/speech/generator/actions.hpp | 19 +++- src/emel/speech/generator/context.hpp | 3 + src/emel/speech/generator/errors.hpp | 1 - src/emel/speech/generator/sm.hpp | 55 ++++++----- src/emel/speech/predictor/moshi/actions.hpp | 28 ++++-- src/emel/speech/predictor/moshi/events.hpp | 34 ++++++- src/emel/speech/predictor/moshi/guards.hpp | 18 ++++ src/emel/speech/predictor/moshi/sm.hpp | 98 +++++++++++++------ tests/speech/generator/lifecycle_tests.cpp | 55 ++++++++--- .../predictor/moshi_lifecycle_tests.cpp | 82 ++++++++++------ .../bench/speech/personaplex_emel_runner.cpp | 6 ++ 11 files changed, 289 insertions(+), 110 deletions(-) diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index 6c06e796..aab5357e 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -473,6 +473,20 @@ struct effect_tokenize_frame { template struct effect_predict_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + typename dependencies_type::predict_event request{ + std::span{ctx.collaborators.model_codes}, + ctx.collaborators.prediction_workspace}; + request.error_out = &runtime_ev.ctx.child_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.predictor.process_event(request); + } +}; + +template +struct effect_sample_frame { void operator()(const runtime_event_type &runtime_ev, context &ctx) const noexcept { runtime_ev.ctx.child_err = 0; @@ -480,13 +494,14 @@ struct effect_predict_frame { runtime_ev.ctx.predicted_text_token = -1; std::fill(ctx.collaborators.predicted_codes.begin(), ctx.collaborators.predicted_codes.end(), -1); - typename dependencies_type::predict_event request{ + typename dependencies_type::sample_event request{ + ctx.collaborators.prediction_workspace, std::span{ctx.collaborators.model_codes}, ctx.collaborators.predicted_codes, runtime_ev.ctx.predicted_text_token}; request.error_out = &runtime_ev.ctx.child_err; request.graph_error_out = &runtime_ev.ctx.graph_err; runtime_ev.ctx.child_accepted = - ctx.collaborators.predictor.process_event(request); + ctx.collaborators.sampler.process_event(request); } }; diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index 14909881..a3e1ebce 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -22,6 +22,7 @@ concept duplex_dependencies = requires(dependencies_type deps) { typename dependencies_type::tokenizer_initialize_event; typename dependencies_type::tokenize_event; typename dependencies_type::predict_event; + typename dependencies_type::sample_event; typename dependencies_type::detokenize_event; typename dependencies_type::capture_tokenizer_state_event; typename dependencies_type::restore_tokenizer_state_event; @@ -33,6 +34,8 @@ concept duplex_dependencies = requires(dependencies_type deps) { deps.decoder; deps.runtime; deps.predictor; + deps.sampler; + deps.prediction_workspace; deps.encoder_initialize; deps.decoder_initialize; deps.runtime_initialize; diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp index b307c48d..540a774d 100644 --- a/src/emel/speech/generator/errors.hpp +++ b/src/emel/speech/generator/errors.hpp @@ -9,7 +9,6 @@ enum class error : emel::error::type { uninitialized = (1u << 0), already_initialized = (1u << 1), invalid_request = (1u << 2), - cutover_pending = (1u << 3), internal_error = (1u << 4), memory_initialize_failed = (1u << 5), encoder_initialize_failed = (1u << 6), diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index cb4a3da2..dc0faa4e 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -54,6 +54,7 @@ struct state_generate_done_channel_decision {}; struct state_stream_encode_result {}; struct state_stream_tokenize_result {}; struct state_stream_predict_result {}; +struct state_stream_sample_result {}; struct state_stream_detokenize_result {}; struct state_stream_decode_result {}; struct state_stream_done_channel_decision {}; @@ -63,6 +64,7 @@ struct state_flushing {}; struct state_flush_encode_result {}; struct state_flush_tokenize_result {}; struct state_flush_predict_result {}; +struct state_flush_sample_result {}; struct state_flush_detokenize_result {}; struct state_flush_decode_result {}; struct state_flush_done_channel_decision {}; @@ -325,26 +327,11 @@ template struct duplex_model { + sml::completion [ condition_error_absent{} ] //------------------------------------------------------------------------------// - // Offline synthesis remains explicitly reserved for its later cutover. - , sml::state <= sml::state - + sml::event [ guard::guard_generate_request_valid{} ] - / action::effect_prepare_generate{} - , sml::state <= sml::state - + sml::event [ guard::guard_generate_request_invalid{} ] - / action::effect_fail_generate{} - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion - , sml::state <= sml::state - + sml::completion + // Duplex generators expose streaming requests; offline synthesis is a + // distinct, explicitly unsupported request shape for this composition. , sml::state <= - sml::state + sml::completion - / action::effect_fail_generate{} + sml::state + sml::event + / action::effect_fail_generate{} , sml::state <= sml::state + sml::completion [ generate_error_present{} ] / action::effect_emit_generation_error{} @@ -352,7 +339,7 @@ template struct duplex_model { + sml::completion [ generate_error_absent{} ] //------------------------------------------------------------------------------// - // Duplex encode -> tokenize -> predict -> detokenize -> optional decode. + // Duplex encode -> tokenize -> predict -> sample -> detokenize -> decode. , sml::state <= sml::state + sml::event [ guard::guard_stream_request_valid{} ] / action::effect_encode_stream_frame{} @@ -373,13 +360,20 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_stream_frame{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] - / action::effect_detokenize_frame{} + / action::effect_sample_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_failed{} ] / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_prediction_succeeded{} ] + / action::effect_detokenize_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_prediction_failed{} ] + / action::effect_fail_stream_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_frame_produced{} ] / action::effect_decode_frame{} @@ -438,13 +432,20 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_flush{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] - / action::effect_detokenize_frame{} + / action::effect_sample_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_failed{} ] / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ guard::guard_prediction_succeeded{} ] + / action::effect_detokenize_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_prediction_failed{} ] + / action::effect_fail_flush{} , sml::state <= sml::state + sml::completion [ guard::guard_frame_produced{} ] / action::effect_decode_frame{} @@ -482,10 +483,10 @@ template struct duplex_model { / action::effect_reject_reset{} , sml::state <= sml::state + sml::event - / action::effect_reject_reset{} + / action::effect_reject_reset{} , sml::state <= sml::state + sml::event - / action::effect_reject_reset{} + / action::effect_reject_reset{} , sml::state <= sml::state + sml::event / action::effect_reject_reset{} @@ -735,7 +736,7 @@ template struct synthesis_model { + sml::event / action::effect_reject_reset{} , sml::state <= sml::state + sml::event - / action::effect_reject_reset{} + / action::effect_reject_reset{} , sml::state <= sml::state + sml::event / action::effect_reject_reset{} , sml::state <= sml::state diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index d4604f89..9562039a 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -606,18 +606,32 @@ struct effect_begin_predict { void operator()(const event::predict_run &runtime_ev, const context &) const noexcept { runtime_ev.ctx.err = detail_ns::to_error(error::none); + } +}; + +struct effect_publish_predict { + void operator()(const event::predict_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + } +}; + +struct effect_begin_sample { + void operator()(const event::sample_run &runtime_ev, + const context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); runtime_ev.ctx.graph_accepted = false; } }; -struct effect_run_predict_graph { - void operator()(const event::predict_run &runtime_ev, +struct effect_run_sample_graph { + void operator()(const event::sample_run &runtime_ev, context &ctx) const noexcept { runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); event::graph_step graph_step{ *ctx.session.model, - runtime_ev.ctx.memory_snapshot, + runtime_ev.request.prediction_workspace.memory, runtime_ev.request.model_tokens, runtime_ev.request.audio_tokens_out, runtime_ev.request.text_token_out, @@ -629,15 +643,15 @@ struct effect_run_predict_graph { } }; -struct effect_publish_predict { - void operator()(const event::predict_run &runtime_ev, +struct effect_publish_sample { + void operator()(const event::sample_run &runtime_ev, context &) const noexcept { runtime_ev.ctx.err = detail_ns::to_error(error::none); } }; -struct effect_store_predict_graph_error_out { - void operator()(const event::predict_run &runtime_ev, +struct effect_store_sample_graph_error_out { + void operator()(const event::sample_run &runtime_ev, context &) const noexcept { *runtime_ev.request.graph_error_out = runtime_ev.ctx.graph_error; } diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 6ab8f848..8b928317 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -88,12 +88,29 @@ struct prefill_personaplex_prompt { }; struct predict { + struct workspace { + emel::memory::view::snapshot memory = {}; + }; + predict(std::span model_tokens_ref, - std::span audio_tokens_out_ref, - int32_t &text_token_out_ref) noexcept - : model_tokens(model_tokens_ref), audio_tokens_out(audio_tokens_out_ref), + workspace &workspace_ref) noexcept + : model_tokens(model_tokens_ref), prediction_workspace(workspace_ref) {} + + std::span model_tokens = {}; + workspace &prediction_workspace; + emel::error::type *error_out = nullptr; +}; + +struct sample { + sample(predict::workspace &workspace_ref, + std::span model_tokens_ref, + std::span audio_tokens_out_ref, + int32_t &text_token_out_ref) noexcept + : prediction_workspace(workspace_ref), model_tokens(model_tokens_ref), + audio_tokens_out(audio_tokens_out_ref), text_token_out(text_token_out_ref) {} + predict::workspace &prediction_workspace; std::span model_tokens = {}; std::span audio_tokens_out = {}; int32_t &text_token_out; @@ -202,9 +219,13 @@ struct predict_ctx { bool memory_accepted = false; int32_t memory_error = static_cast(emel::error::cast(error::none)); int32_t memory_block_count = 0; + emel::memory::view::snapshot &memory_snapshot; +}; + +struct sample_ctx { + emel::error::type err = emel::error::cast(error::none); bool graph_accepted = false; emel::error::type graph_error = emel::error::cast(error::none); - emel::memory::view::snapshot &memory_snapshot; }; struct initialize_run { @@ -237,6 +258,11 @@ struct predict_run { predict_ctx &ctx; }; +struct sample_run { + const sample &request; + sample_ctx &ctx; +}; + struct reset_run { const reset &request; }; diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index cfd09db0..e221d6e3 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -133,6 +133,17 @@ struct guard_predict_request_valid { const action::context &ctx) const noexcept { const bool voice_ready = !ctx.voice.loaded || (ctx.voice.ready && ctx.voice.prompt_ready); + return ctx.session.model != nullptr && voice_ready && + runtime_ev.request.model_tokens.size() == + static_cast(ctx.lmgen.codebook_count); + } +}; + +struct guard_sample_request_valid { + bool operator()(const event::sample_run &runtime_ev, + const action::context &ctx) const noexcept { + const bool voice_ready = + !ctx.voice.loaded || (ctx.voice.ready && ctx.voice.prompt_ready); return ctx.session.model != nullptr && voice_ready && runtime_ev.request.model_tokens.size() == static_cast(ctx.lmgen.codebook_count) && @@ -141,6 +152,13 @@ struct guard_predict_request_valid { } }; +struct guard_sample_request_invalid { + bool operator()(const event::sample_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_sample_request_valid{}(runtime_ev, ctx); + } +}; + struct guard_predict_blocked_by_voice_prompt { bool operator()(const event::predict_run &, const action::context &ctx) const noexcept { diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index d40e0a7a..546d6e50 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -84,12 +84,16 @@ struct state_predict_allocate_slot_decision {}; struct state_predict_capture_memory {}; struct state_predict_capture_memory_decision {}; struct state_predict_begin {}; -struct state_predict_graph_runtime_decision {}; -struct state_predict_running_graph {}; -struct state_predict_graph_error_out_decision {}; -struct state_predict_graph_result_decision {}; struct state_predict_error_out_decision {}; struct state_predict_failed_error_out_decision {}; +struct state_sample_request_decision {}; +struct state_sample_begin {}; +struct state_sample_graph_runtime_decision {}; +struct state_sample_running_graph {}; +struct state_sample_graph_error_out_decision {}; +struct state_sample_graph_result_decision {}; +struct state_sample_error_out_decision {}; +struct state_sample_failed_error_out_decision {}; struct state_uninit_voice_error_out_decision {}; struct state_uninit_voice_callback_decision {}; struct state_uninit_prefill_voice_error_out_decision {}; @@ -108,6 +112,7 @@ struct model { using prefill_prompt_run = event::prefill_personaplex_prompt_run; using prefill_voice_run = event::prefill_voice_run; using predict_run = event::predict_run; + using sample_run = event::sample_run; // clang-format off return sml::make_transition_table( @@ -472,30 +477,9 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_memory_rejected{} ] / action::effect_mark_memory_error{} - , sml::state <= - sml::state + sml::completion - , sml::state <= - sml::state + sml::completion - [ guard::guard_graph_runtime_available{} ] / action::effect_run_predict_graph{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_graph_runtime_unavailable{} ] - / action::effect_mark_graph_runtime_unavailable{} - , sml::state <= - sml::state + sml::completion - , sml::state <= - sml::state + sml::completion - [ guard::guard_has_graph_error_out{} ] / action::effect_store_predict_graph_error_out{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_no_graph_error_out{} ] , sml::state <= - sml::state + sml::completion - [ guard::guard_graph_step_accepted{} ] / action::effect_publish_predict{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_graph_step_rejected{} ] - / action::effect_mark_graph_runtime_error{} + sml::state + sml::completion + / action::effect_publish_predict{} , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] / action::effect_store_error_out{} @@ -507,6 +491,51 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_no_error_out{} ] + // Model-family sampling executes only after prediction memory is prepared. + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_sample_request_valid{} ] + / action::effect_begin_sample{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_sample_request_invalid{} ] + / action::effect_mark_step_request_invalid{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_runtime_available{} ] / action::effect_run_sample_graph{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_runtime_unavailable{} ] + / action::effect_mark_graph_runtime_unavailable{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_has_graph_error_out{} ] / action::effect_store_sample_graph_error_out{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_no_graph_error_out{} ] + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_accepted{} ] / action::effect_publish_sample{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_rejected{} ] + / action::effect_mark_graph_runtime_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + // Predictor-owned prompt cache handoff into the injected tokenizer. , sml::state <= sml::state + sml::event @@ -525,6 +554,12 @@ struct model { , sml::state <= sml::state + sml::event [ guard::guard_no_error_out{} ] / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::event [ guard::guard_has_error_out{} ] + / action::effect_mark_not_initialized_and_store{} + , sml::state <= sml::state + + sml::event [ guard::guard_no_error_out{} ] + / action::effect_mark_not_initialized{} , sml::state <= sml::state + sml::event / action::effect_reject_capture_tokenizer_state{} @@ -660,12 +695,19 @@ struct sm : public emel::sm { } bool process_event(const event::predict &ev) { - event::predict_ctx ctx{*memory_snapshot_}; + event::predict_ctx ctx{ev.prediction_workspace.memory}; event::predict_run runtime_ev{ev, ctx}; const bool accepted = base_type::process_event(runtime_ev); return accepted && ctx.err == action::detail_ns::to_error(error::none); } + bool process_event(const event::sample &ev) { + event::sample_ctx ctx{}; + event::sample_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + bool process_event(const event::capture_tokenizer_state &ev) { const bool accepted = base_type::process_event(ev); return accepted && ev.error_out == action::detail_ns::to_error(error::none); diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index c48c520c..4b8ccfcb 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -49,13 +49,27 @@ struct fake_encode { emel::error::type *error_out = nullptr; }; +struct fake_prediction_workspace {}; + struct fake_predict { fake_predict(std::span tokens_ref, - std::span tokens_out_ref, - int32_t &text_token_out_ref) noexcept - : tokens(tokens_ref), tokens_out(tokens_out_ref), - text_token_out(text_token_out_ref) {} + fake_prediction_workspace &workspace_ref) noexcept + : tokens(tokens_ref), workspace(workspace_ref) {} + std::span tokens; + fake_prediction_workspace &workspace; + emel::error::type *error_out = nullptr; +}; + +struct fake_sample { + fake_sample(fake_prediction_workspace &workspace_ref, + std::span tokens_ref, + std::span tokens_out_ref, + int32_t &text_token_out_ref) noexcept + : workspace(workspace_ref), tokens(tokens_ref), + tokens_out(tokens_out_ref), text_token_out(text_token_out_ref) {} + + fake_prediction_workspace &workspace; std::span tokens; std::span tokens_out; int32_t &text_token_out; @@ -212,11 +226,13 @@ struct fake_predictor_actor { int32_t prompt_begin_calls = 0; int32_t prompt_condition_calls = 0; int32_t predict_calls = 0; + int32_t sample_calls = 0; int32_t rejected_initialize_call = 0; bool voice_accepted = true; bool prompt_begin_accepted = true; bool prompt_accepted = true; bool predict_accepted = true; + bool sample_accepted = true; emel::error::type initialize_error = 0; emel::error::type voice_error = 0; emel::error::type voice_graph_error = 0; @@ -224,7 +240,8 @@ struct fake_predictor_actor { emel::error::type prompt_error = 0; emel::error::type prompt_graph_error = 0; emel::error::type predict_error = 0; - emel::error::type predict_graph_error = 0; + emel::error::type sample_error = 0; + emel::error::type sample_graph_error = 0; bool voice_complete = true; bool prompt_complete = true; @@ -260,12 +277,18 @@ struct fake_predictor_actor { bool process_event(const fake_predict &request) noexcept { ++predict_calls; + *request.error_out = predict_error; + return predict_accepted; + } + + bool process_event(const fake_sample &request) noexcept { + ++sample_calls; request.tokens_out[0] = request.tokens[0] + 100; request.tokens_out[1] = request.tokens[1] + 100; request.text_token_out = 42; - *request.error_out = predict_error; - *request.graph_error_out = predict_graph_error; - return predict_accepted; + *request.error_out = sample_error; + *request.graph_error_out = sample_graph_error; + return sample_accepted; } bool process_event(const fake_capture_tokenizer_state &request) noexcept { @@ -285,6 +308,7 @@ struct fake_dependencies { using tokenizer_initialize_event = fake_tokenizer_initialize; using tokenize_event = fake_tokenize; using predict_event = fake_predict; + using sample_event = fake_sample; using detokenize_event = fake_detokenize; using capture_tokenizer_state_event = fake_capture_tokenizer_state; using restore_tokenizer_state_event = fake_restore_tokenizer_state; @@ -297,6 +321,8 @@ struct fake_dependencies { fake_decoder_actor &decoder; fake_runtime_actor &runtime; fake_predictor_actor &predictor; + fake_predictor_actor &sampler; + fake_prediction_workspace &prediction_workspace; fake_initialize encoder_initialize = {}; fake_initialize decoder_initialize = {}; fake_initialize runtime_initialize = {}; @@ -329,6 +355,7 @@ struct fixture { fake_decoder_actor decoder{}; fake_runtime_actor runtime{}; fake_predictor_actor predictor{}; + fake_prediction_workspace prediction_workspace{}; fake_dependencies dependencies; generator::sm machine; @@ -342,6 +369,8 @@ struct fixture { .decoder = decoder, .runtime = runtime, .predictor = predictor, + .sampler = predictor, + .prediction_workspace = prediction_workspace, .silence_pcm = std::span{silence}, .input_codes = std::span{input_codes}, .tokenize_input_codes = std::span{input_codes}, @@ -686,7 +715,7 @@ TEST_CASE("speech_generator_keeps_offline_synthesis_failure_explicit") { CHECK(sample_count == 0); CHECK(probe.error_calls == 1); CHECK(probe.last_error == - generator::action::error_code(generator::error::cutover_pending)); + generator::action::error_code(generator::error::unsupported_request)); CHECK(test->machine.is(sml::state)); } @@ -718,6 +747,8 @@ TEST_CASE("speech_generator_streams_through_injected_actor_pipeline") { CHECK(encoded == std::array{11, 12}); CHECK(generated == std::array{111, 112}); CHECK(text_token == 42); + CHECK(test->predictor.predict_calls == 1); + CHECK(test->predictor.sample_calls == 1); CHECK(sample_count == 4); CHECK(produced); CHECK(pcm_out[0] == doctest::Approx(0.25f)); @@ -776,14 +807,14 @@ TEST_CASE("speech_generator_streams_pending_frames_and_reports_failures") { generator::action::error_code(generator::error::encode_failed)); } - SUBCASE("predict failure") { - test->predictor.predict_graph_error = 4; + SUBCASE("sample failure") { + test->predictor.sample_graph_error = 4; request.on_error = decltype(request.on_error)::from(&probe); CHECK_FALSE(test->machine.process_event(request)); CHECK(probe.last_error == - generator::action::error_code(generator::error::predict_failed)); + generator::action::error_code(generator::error::sample_failed)); } SUBCASE("decode failure") { diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 02cc4be2..2b442f95 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -281,12 +281,10 @@ void initialize_streaming_position(memory_streaming::sm &position) { TEST_CASE("speech_moshi_predictor_rejects_predict_before_initialize") { moshi::sm generator{}; std::array input = {0, 0, 0, 0}; - std::array output = {}; - int32_t text_token = -1; + moshi::event::predict::workspace workspace{}; emel::error::type err = k_no_error; - moshi::event::predict predict{std::span{input}, - std::span{output}, text_token}; + moshi::event::predict predict{std::span{input}, workspace}; predict.error_out = &err; CHECK_FALSE(generator.process_event(predict)); @@ -390,16 +388,13 @@ TEST_CASE( REQUIRE(generator.process_event(load)); CHECK(err == k_no_error); - std::array output = {}; std::array model_tokens = {}; - int32_t text_token = -1; + moshi::event::predict::workspace workspace{}; moshi::event::predict blocked_predict{ std::span{ model_tokens.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - std::span{output.data(), - static_cast(fixture.model->moshi_lm.dep_q)}, - text_token}; + workspace}; blocked_predict.error_out = &err; CHECK_FALSE(generator.process_event(blocked_predict)); CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); @@ -506,15 +501,14 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" REQUIRE(needed_tokens >= 0); std::array input = {}; std::array output = {}; + moshi::event::predict::workspace workspace{}; std::fill(input.begin(), input.end(), 0); int32_t text_token = -1; err = k_no_error; moshi::event::predict blocked_predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - std::span{output.data(), - static_cast(fixture.model->moshi_lm.dep_q)}, - text_token}; + workspace}; blocked_predict.error_out = &err; CHECK_FALSE(generator.process_event(blocked_predict)); CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); @@ -560,14 +554,21 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" err = k_no_error; emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); moshi::event::predict first_predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + workspace}; + first_predict.error_out = &err; + REQUIRE(generator.process_event(first_predict)); + moshi::event::sample first_sample{ + workspace, std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; - first_predict.error_out = &err; - first_predict.graph_error_out = &graph_err; - REQUIRE(generator.process_event(first_predict)); + first_sample.error_out = &err; + first_sample.graph_error_out = &graph_err; + REQUIRE(generator.process_event(first_sample)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); CHECK(graph.call_count == prompt_frames + 5); @@ -622,17 +623,15 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" REQUIRE(needed_tokens >= 0); std::array input = {}; std::array output = {}; + moshi::event::predict::workspace workspace{}; std::fill(input.begin(), input.end(), 0); int32_t text_token = -1; emel::error::type graph_err = emel::error::cast(moshi::error::graph_runtime); moshi::event::predict predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - std::span{output.data(), - static_cast(fixture.model->moshi_lm.dep_q)}, - text_token}; + workspace}; predict.error_out = &err; - predict.graph_error_out = &graph_err; err = k_no_error; CHECK_FALSE(generator.process_event(predict)); @@ -665,6 +664,16 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" err = k_no_error; graph_err = emel::error::cast(moshi::error::graph_runtime); REQUIRE(generator.process_event(predict)); + moshi::event::sample sample{ + workspace, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + std::span{output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + text_token}; + sample.error_out = &err; + sample.graph_error_out = &graph_err; + REQUIRE(generator.process_event(sample)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); CHECK(graph.call_count == prompt_frames + personaplex_prompt_frames + 1); @@ -686,17 +695,26 @@ TEST_CASE("speech_moshi_predictor_uses_memory_then_reports_missing_graph_" std::array input = {}; std::array output = {}; + moshi::event::predict::workspace workspace{}; int32_t text_token = -1; err = k_no_error; moshi::event::predict predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + workspace}; + predict.error_out = &err; + + REQUIRE(generator.process_event(predict)); + moshi::event::sample sample{ + workspace, std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; - predict.error_out = &err; + sample.error_out = &err; - CHECK_FALSE(generator.process_event(predict)); + CHECK_FALSE(generator.process_event(sample)); CHECK(err == emel::error::cast(moshi::error::graph_runtime_unavailable)); CHECK(kv.allocate_slots_count == 1); CHECK(kv.capture_view_count == 1); @@ -997,7 +1015,7 @@ TEST_CASE("speech_moshi_generator_graph_outputs_use_explicit_transitions") { std::string::npos); CHECK(actions_source.find("effect_store_graph_debug_phase_out") == std::string::npos); - CHECK(sm_source.find("state_predict_graph_error_out_decision") != + CHECK(sm_source.find("state_sample_graph_error_out_decision") != std::string::npos); CHECK(sm_source.find("state_graph_debug_phase_out_decision") == std::string::npos); @@ -1018,14 +1036,12 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { moshi::action::effect_configure_standard_lmgen{}(init_run, generator_ctx); CHECK(generator_ctx.lmgen.delayed_dep_q == fixture.model->moshi_lm.dep_q); + moshi::event::predict::workspace generator_workspace{}; + moshi::event::predict_ctx generator_predict_ctx{generator_workspace.memory}; auto generator_snapshot = std::make_unique(); - moshi::event::predict_ctx generator_predict_ctx{*generator_snapshot}; std::array generator_input = {}; - std::array generator_output = {}; - int32_t generator_text = -1; moshi::event::predict generator_predict{ - std::span{generator_input.data(), 1}, - std::span{generator_output.data(), 1}, generator_text}; + std::span{generator_input.data(), 1}, generator_workspace}; moshi::event::predict_run generator_predict_run{generator_predict, generator_predict_ctx}; moshi::action::effect_mark_memory_error{}( @@ -1839,17 +1855,25 @@ TEST_CASE( std::array input = {}; std::array output = {}; + moshi::event::predict::workspace workspace{}; output.fill(-1); int32_t text_token = -1; moshi::event::predict predict{ + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + workspace}; + predict.error_out = &err; + REQUIRE(generator.process_event(predict)); + moshi::event::sample sample{ + workspace, std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; - predict.error_out = &err; + sample.error_out = &err; - CHECK_FALSE(generator.process_event(predict)); + CHECK_FALSE(generator.process_event(sample)); CHECK(err == emel::error::cast(moshi::error::graph_runtime)); CHECK(kv.allocate_slots_count == 1); CHECK(kv.capture_view_count == 1); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 2b387c77..25b5ff25 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -99,6 +99,7 @@ struct personaplex_dependencies { using tokenizer_initialize_event = tokenizer::event::initialize; using tokenize_event = tokenizer::event::tokenize; using predict_event = predictor::event::predict; + using sample_event = predictor::event::sample; using detokenize_event = tokenizer::event::detokenize; using capture_tokenizer_state_event = predictor::event::capture_tokenizer_state; @@ -112,6 +113,8 @@ struct personaplex_dependencies { mimi::sm &decoder; runtime::sm &runtime; predictor::sm &predictor; + predictor::sm &sampler; + predictor::event::predict::workspace &prediction_workspace; mimi::event::initialize encoder_initialize; mimi::event::initialize decoder_initialize; runtime::event::initialize runtime_initialize; @@ -535,6 +538,7 @@ int main(int argc, char **argv) { predictor::sm token_predictor{ emel::memory::hybrid::kv_binding{}, runtime::bind_graph_executor(prediction_runtime)}; + predictor::event::predict::workspace prediction_workspace{}; tokenizer::sm token_delay{tokenizer::dependencies{ .delays = std::span{delay_begin, delay_end}, .cache = std::span{tokenizer_storage}, @@ -572,6 +576,8 @@ int main(int argc, char **argv) { .decoder = decoder, .runtime = prediction_runtime, .predictor = token_predictor, + .sampler = token_predictor, + .prediction_workspace = prediction_workspace, .encoder_initialize = mimi::event::initialize{*mimi_model.model, std::span{encoder_prepared}, From 76f2f9244a1363e4039b39e1f80df2b589aba2ff Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 19:56:06 -0500 Subject: [PATCH 18/61] refactor: remove speech compatibility aliases --- src/emel/memory/streaming/sm.hpp | 2 -- src/emel/speech/codec/mimi/any.hpp | 2 -- src/emel/speech/codec/mimi/sm.hpp | 2 -- src/emel/speech/decoder/whisper/sm.hpp | 2 -- src/emel/speech/encoder/whisper/sm.hpp | 2 -- src/emel/speech/generator/any.hpp | 7 ------- src/emel/speech/generator/sm.hpp | 2 -- src/emel/speech/predictor/moshi/any.hpp | 6 ------ src/emel/speech/predictor/moshi/executor/any.hpp | 2 -- src/emel/speech/predictor/moshi/executor/sm.hpp | 2 -- src/emel/speech/predictor/moshi/sm.hpp | 2 -- src/emel/speech/recognizer/sm.hpp | 2 -- src/emel/speech/tokenizer/moshi/any.hpp | 6 ------ src/emel/speech/tokenizer/moshi/sm.hpp | 2 -- 14 files changed, 41 deletions(-) diff --git a/src/emel/memory/streaming/sm.hpp b/src/emel/memory/streaming/sm.hpp index ee47687d..94025007 100644 --- a/src/emel/memory/streaming/sm.hpp +++ b/src/emel/memory/streaming/sm.hpp @@ -187,6 +187,4 @@ struct sm : public emel::sm { explicit sm(const dependencies &deps) : base_type(std::in_place, deps) {} }; -using Streaming = sm; - } // namespace emel::memory::streaming diff --git a/src/emel/speech/codec/mimi/any.hpp b/src/emel/speech/codec/mimi/any.hpp index 8806b83e..046a38af 100644 --- a/src/emel/speech/codec/mimi/any.hpp +++ b/src/emel/speech/codec/mimi/any.hpp @@ -7,8 +7,6 @@ namespace emel::speech::codec::mimi { -using MimiCodec = sm; - // Public arena-sizing contract for event::initialize: the caller owns the // four arenas, sizes them here before dispatching initialize, and keeps them // alive for the codec's lifetime (the machine never allocates). A result of diff --git a/src/emel/speech/codec/mimi/sm.hpp b/src/emel/speech/codec/mimi/sm.hpp index fb028155..30cc3d3c 100644 --- a/src/emel/speech/codec/mimi/sm.hpp +++ b/src/emel/speech/codec/mimi/sm.hpp @@ -475,6 +475,4 @@ struct sm : public emel::sm { } }; -using Codec = sm; - } // namespace emel::speech::codec::mimi diff --git a/src/emel/speech/decoder/whisper/sm.hpp b/src/emel/speech/decoder/whisper/sm.hpp index fe24c67a..52102149 100644 --- a/src/emel/speech/decoder/whisper/sm.hpp +++ b/src/emel/speech/decoder/whisper/sm.hpp @@ -199,6 +199,4 @@ struct sm : public emel::sm { } }; -using Decoder = sm; - } // namespace emel::speech::decoder::whisper diff --git a/src/emel/speech/encoder/whisper/sm.hpp b/src/emel/speech/encoder/whisper/sm.hpp index 0c57f974..3490ca0d 100644 --- a/src/emel/speech/encoder/whisper/sm.hpp +++ b/src/emel/speech/encoder/whisper/sm.hpp @@ -200,6 +200,4 @@ struct sm : public emel::sm { } }; -using Encoder = sm; - } // namespace emel::speech::encoder::whisper diff --git a/src/emel/speech/generator/any.hpp b/src/emel/speech/generator/any.hpp index 55eed06f..8ec950ca 100644 --- a/src/emel/speech/generator/any.hpp +++ b/src/emel/speech/generator/any.hpp @@ -1,10 +1,3 @@ #pragma once #include "emel/speech/generator/sm.hpp" - -namespace emel::speech::generator { - -template -using SpeechGenerator = sm; - -} // namespace emel::speech::generator diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index dc0faa4e..c6b8093b 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -816,6 +816,4 @@ struct sm : public emel::sm, template sm(const dependencies_type &) -> sm; -template using Generator = sm; - } // namespace emel::speech::generator diff --git a/src/emel/speech/predictor/moshi/any.hpp b/src/emel/speech/predictor/moshi/any.hpp index 53c2d48f..206b6625 100644 --- a/src/emel/speech/predictor/moshi/any.hpp +++ b/src/emel/speech/predictor/moshi/any.hpp @@ -1,9 +1,3 @@ #pragma once #include "emel/speech/predictor/moshi/sm.hpp" - -namespace emel::speech::predictor::moshi { - -using MoshiGenerator = sm; - -} // namespace emel::speech::predictor::moshi diff --git a/src/emel/speech/predictor/moshi/executor/any.hpp b/src/emel/speech/predictor/moshi/executor/any.hpp index 7f713a19..d80ec15f 100644 --- a/src/emel/speech/predictor/moshi/executor/any.hpp +++ b/src/emel/speech/predictor/moshi/executor/any.hpp @@ -47,6 +47,4 @@ bind_kv_caches(const temporal_kv_binding &temporal, depformer_positions); } -using MoshiExecutor = sm; - } // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 11583a0f..1f0bb880 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -1029,6 +1029,4 @@ struct sm : public emel::sm { } }; -using Executor = sm; - } // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 546d6e50..975bb310 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -722,6 +722,4 @@ struct sm : public emel::sm { std::unique_ptr memory_snapshot_ = {}; }; -using Generator = sm; - } // namespace emel::speech::predictor::moshi diff --git a/src/emel/speech/recognizer/sm.hpp b/src/emel/speech/recognizer/sm.hpp index 1e76b429..d2188511 100644 --- a/src/emel/speech/recognizer/sm.hpp +++ b/src/emel/speech/recognizer/sm.hpp @@ -220,8 +220,6 @@ struct sm : public emel::sm, action::context> { } }; -using Recognizer = sm<>; - } // namespace emel::speech::recognizer namespace emel { diff --git a/src/emel/speech/tokenizer/moshi/any.hpp b/src/emel/speech/tokenizer/moshi/any.hpp index bcb4c219..81d682d6 100644 --- a/src/emel/speech/tokenizer/moshi/any.hpp +++ b/src/emel/speech/tokenizer/moshi/any.hpp @@ -1,9 +1,3 @@ #pragma once #include "emel/speech/tokenizer/moshi/sm.hpp" - -namespace emel::speech::tokenizer::moshi { - -using Tokenizer = sm; - -} // namespace emel::speech::tokenizer::moshi diff --git a/src/emel/speech/tokenizer/moshi/sm.hpp b/src/emel/speech/tokenizer/moshi/sm.hpp index 0123320a..36d967ca 100644 --- a/src/emel/speech/tokenizer/moshi/sm.hpp +++ b/src/emel/speech/tokenizer/moshi/sm.hpp @@ -270,6 +270,4 @@ struct sm : public emel::sm { } }; -using Moshi = sm; - } // namespace emel::speech::tokenizer::moshi From dd44d50b101ebecae2c567bd9619a8077fc805aa Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 19:56:10 -0500 Subject: [PATCH 19/61] test: route speech cutover through personaplex parity --- scripts/quality_gates.sh | 23 +++++++++++++++++++++++ tools/bench/quality_gates_tests.cpp | 13 +++++++++++++ 2 files changed, 36 insertions(+) diff --git a/scripts/quality_gates.sh b/scripts/quality_gates.sh index 48bec0f0..87e95618 100755 --- a/scripts/quality_gates.sh +++ b/scripts/quality_gates.sh @@ -16,6 +16,7 @@ QUALITY_GATES_BENCH_RUNS="${EMEL_QUALITY_GATES_BENCH_RUNS:-3}" QUALITY_GATES_BENCH_WARMUP_ITERS="${EMEL_QUALITY_GATES_BENCH_WARMUP_ITERS:-10}" QUALITY_GATES_BENCH_WARMUP_RUNS="${EMEL_QUALITY_GATES_BENCH_WARMUP_RUNS:-1}" QUALITY_GATES_BENCH_TOLERANCE="${EMEL_QUALITY_GATES_BENCH_TOLERANCE:-0.30}" +QUALITY_GATES_PERSONAPLEX_FRAMES="${EMEL_QUALITY_GATES_PERSONAPLEX_FRAMES:-40}" QUALITY_GATES_GENERATION_BENCH_ITERS="${EMEL_QUALITY_GATES_GENERATION_BENCH_ITERS:-1}" QUALITY_GATES_GENERATION_BENCH_RUNS="${EMEL_QUALITY_GATES_GENERATION_BENCH_RUNS:-1}" QUALITY_GATES_GENERATION_BENCH_WARMUP_ITERS="${EMEL_QUALITY_GATES_GENERATION_BENCH_WARMUP_ITERS:-0}" @@ -847,6 +848,15 @@ infer_quality_gate_scope() { src/emel/batch/*|tests/batch/*) add_bench_suite batch_planner "scope path=$file" ;; + src/emel/speech/codec/mimi/*|src/emel/speech/generator/*|\ + src/emel/speech/predictor/moshi/*|\ + src/emel/speech/tokenizer/moshi/*|tests/speech/generator/*|\ + tests/speech/codec/mimi*|tests/speech/predictor/*|\ + tests/speech/tokenizer/moshi/*|\ + tools/bench/personaplex*|tools/bench/speech/personaplex*|\ + scripts/bench_personaplex_compare.sh) + add_bench_suite speech_dialogue_moshi "scope path=$file" + ;; src/emel/io/*|src/emel/io/**/*|tests/io/*|tests/io/**/*) ;; src/emel/kernel/aarch64/*|tests/kernel/aarch64*) @@ -1200,6 +1210,19 @@ run_benchmark_gates() { continue fi ;; + speech_dialogue_moshi) + # PersonaPlex is an end-to-end dialogue lane rather than a bench_runner + # microbenchmark. It owns the maintained encoder -> tokenizer -> + # predictor -> sampler -> detokenizer -> decoder comparison. + if run_step_allow_fail "bench_snapshot_${suite}" \ + "$ROOT_DIR/scripts/bench_personaplex_compare.sh" \ + --frames "$QUALITY_GATES_PERSONAPLEX_FRAMES"; then + continue + else + status=$? + continue + fi + ;; speech_codec_mimi) # The generic bench path runs codec_mimi_bench with placeholder # reference rows only; the token-exact Moshi comparison lives in the diff --git a/tools/bench/quality_gates_tests.cpp b/tools/bench/quality_gates_tests.cpp index d1485651..151dd4f6 100644 --- a/tools/bench/quality_gates_tests.cpp +++ b/tools/bench/quality_gates_tests.cpp @@ -364,6 +364,19 @@ TEST_CASE("bench script routes Moshi LM suite through the wrapper") { std::string::npos); } +TEST_CASE("quality gates route PersonaPlex changes through end-to-end compare") { + const std::string script = + read_file(repo_root() / "scripts" / "quality_gates.sh"); + + CHECK(script.find("add_bench_suite speech_dialogue_moshi") != + std::string::npos); + CHECK(script.find("speech_dialogue_moshi)") != std::string::npos); + CHECK(script.find("scripts/bench_personaplex_compare.sh") != + std::string::npos); + CHECK(script.find("QUALITY_GATES_PERSONAPLEX_FRAMES") != + std::string::npos); +} + TEST_CASE("benchmark defaults stay bounded for routine quality gates") { const std::string quality_gates = read_file(repo_root() / "scripts" / "quality_gates.sh"); From 1dd821a00692a9358aa53bd17548844db22055b4 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 20:27:18 -0500 Subject: [PATCH 20/61] refactor: inject moshi executor as typed actor --- src/emel/sm.hpp | 6 ++ src/emel/speech/generator/actions.hpp | 11 ---- src/emel/speech/generator/context.hpp | 2 - src/emel/speech/generator/errors.hpp | 1 - src/emel/speech/generator/sm.hpp | 16 ++--- src/emel/speech/predictor/moshi/actions.hpp | 42 ++++++------ src/emel/speech/predictor/moshi/context.hpp | 22 ++----- src/emel/speech/predictor/moshi/events.hpp | 17 +++++ .../speech/predictor/moshi/executor/any.hpp | 12 ---- .../speech/predictor/moshi/executor/sm.hpp | 15 +++++ src/emel/speech/predictor/moshi/guards.hpp | 32 ++++----- src/emel/speech/predictor/moshi/sm.hpp | 52 +++++++-------- tests/speech/generator/lifecycle_tests.cpp | 17 ----- .../predictor/moshi_lifecycle_tests.cpp | 65 +++++++++++-------- .../bench/speech/personaplex_emel_runner.cpp | 30 ++++----- 15 files changed, 162 insertions(+), 178 deletions(-) diff --git a/src/emel/sm.hpp b/src/emel/sm.hpp index e0745c1b..7b9cf470 100644 --- a/src/emel/sm.hpp +++ b/src/emel/sm.hpp @@ -716,6 +716,12 @@ class sm { explicit sm(std::in_place_t, context_args &&... context_args_in) : context_(std::forward(context_args_in)...), state_machine_(context_) {} + template + requires (sizeof...(args) > 0) + explicit sm(std::piecewise_construct_t, context_arg && context_arg_in, + args &&... args_in) + : context_(std::forward(context_arg_in)), + state_machine_(context_, std::forward(args_in)...) {} explicit sm(const context_type & context_in) : context_(context_in), state_machine_(context_) {} explicit sm(context_type && context_in) diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index aab5357e..f4e5b47b 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -78,17 +78,6 @@ template struct effect_initialize_decoder { } }; -template struct effect_initialize_runtime { - void operator()(const event::initialize_run &runtime_ev, - context &ctx) const noexcept { - runtime_ev.ctx.child_err = 0; - auto request = ctx.collaborators.runtime_initialize; - request.error_out = &runtime_ev.ctx.child_err; - runtime_ev.ctx.child_accepted = - ctx.collaborators.runtime.process_event(request); - } -}; - template struct effect_initialize_predictor { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index a3e1ebce..49354e79 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -32,13 +32,11 @@ concept duplex_dependencies = requires(dependencies_type deps) { deps.encoder; deps.tokenizer; deps.decoder; - deps.runtime; deps.predictor; deps.sampler; deps.prediction_workspace; deps.encoder_initialize; deps.decoder_initialize; - deps.runtime_initialize; deps.predictor_initialize; deps.conditioning_initialize; deps.silence_pcm; diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp index 540a774d..24b3102f 100644 --- a/src/emel/speech/generator/errors.hpp +++ b/src/emel/speech/generator/errors.hpp @@ -13,7 +13,6 @@ enum class error : emel::error::type { memory_initialize_failed = (1u << 5), encoder_initialize_failed = (1u << 6), decoder_initialize_failed = (1u << 7), - runtime_initialize_failed = (1u << 8), predictor_initialize_failed = (1u << 9), conditioning_failed = (1u << 10), encode_failed = (1u << 11), diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index c6b8093b..a18be272 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -17,7 +17,6 @@ struct state_initialize_temporal_result {}; struct state_initialize_secondary_result {}; struct state_initialize_encoder_result {}; struct state_initialize_decoder_result {}; -struct state_initialize_runtime_result {}; struct state_initialize_predictor_result {}; struct state_initialize_conditioning_result {}; struct state_initialize_tokenizer_result {}; @@ -76,7 +75,8 @@ generic speech generator (single source of truth) state purpose - initialization deterministically initializes injected temporal memory, - encoder, decoder, prediction runtime, predictor, and conditioning actors. + encoder, decoder, predictor, conditioning, and tokenizer actors. Model-family + predictors own initialization of their injected execution actors. - condition states advance reference and prompt conditioning one bounded frame per public dispatch. - state_ready accepts offline synthesis or duplex input frames. @@ -171,22 +171,14 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_initialize{} - , sml::state <= + , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_initialize_runtime{} + / action::effect_initialize_predictor{} , sml::state <= sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_initialize{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_child_succeeded{} ] - / action::effect_initialize_predictor{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_child_failed{} ] - / action::effect_fail_initialize{} , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index 9562039a..d66e2f9a 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -61,14 +61,6 @@ struct effect_mark_step_request_invalid { } }; -template -struct effect_mark_graph_runtime_unavailable { - void operator()(const runtime_event_type &runtime_ev, - context &) const noexcept { - runtime_ev.ctx.err = detail_ns::to_error(error::graph_runtime_unavailable); - } -}; - template struct effect_mark_graph_runtime_error { void operator()(const runtime_event_type &runtime_ev, context &) const noexcept { @@ -138,6 +130,16 @@ struct effect_configure_standard_lmgen { } }; +template struct effect_initialize_graph { + void operator()(const event::initialize_run &runtime_ev, context &, + graph_actor_type &graph) const noexcept { + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + event::initialize_graph request{runtime_ev.request}; + request.error_out = &runtime_ev.ctx.graph_error; + runtime_ev.ctx.graph_accepted = graph.process_event(request); + } +}; + struct effect_configure_personaplex_lmgen { void operator()(const event::initialize_run &, context &ctx) const noexcept { ctx.lmgen.delayed_dep_q = ctx.session.model->moshi_lm.inference_dep_q; @@ -330,9 +332,9 @@ struct effect_load_voice_embedding_frame_bf16 { } }; -struct effect_run_voice_graph_runtime { - void operator()(const event::prefill_voice_run &runtime_ev, - context &ctx) const noexcept { +template struct effect_run_voice_graph_runtime { + void operator()(const event::prefill_voice_run &runtime_ev, context &ctx, + graph_actor_type &graph) const noexcept { runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); event::graph_step graph_step{ *ctx.session.model, @@ -349,8 +351,7 @@ struct effect_run_voice_graph_runtime { static_cast(ctx.voice.embedding_dim)}; graph_step.forced_text_token = ctx.session.model->moshi_lm.text_padding_id; graph_step.error_out = &runtime_ev.ctx.graph_error; - runtime_ev.ctx.graph_accepted = - ctx.graph.dispatch_step(ctx.graph.executor, graph_step); + runtime_ev.ctx.graph_accepted = graph.process_event(graph_step); } }; @@ -511,9 +512,10 @@ struct effect_write_and_build_personaplex_prompt_input { } }; +template struct effect_run_personaplex_prompt_graph_runtime { void operator()(const event::prefill_personaplex_prompt_run &runtime_ev, - context &ctx) const noexcept { + context &ctx, graph_actor_type &graph) const noexcept { runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); event::graph_step graph_step{ *ctx.session.model, @@ -526,8 +528,7 @@ struct effect_run_personaplex_prompt_graph_runtime { }; graph_step.sequence_id = ctx.session.sequence_id; graph_step.error_out = &runtime_ev.ctx.graph_error; - runtime_ev.ctx.graph_accepted = - ctx.graph.dispatch_step(ctx.graph.executor, graph_step); + runtime_ev.ctx.graph_accepted = graph.process_event(graph_step); } }; @@ -625,9 +626,9 @@ struct effect_begin_sample { } }; -struct effect_run_sample_graph { - void operator()(const event::sample_run &runtime_ev, - context &ctx) const noexcept { +template struct effect_run_sample_graph { + void operator()(const event::sample_run &runtime_ev, context &ctx, + graph_actor_type &graph) const noexcept { runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); event::graph_step graph_step{ *ctx.session.model, @@ -638,8 +639,7 @@ struct effect_run_sample_graph { }; graph_step.sequence_id = ctx.session.sequence_id; graph_step.error_out = &runtime_ev.ctx.graph_error; - runtime_ev.ctx.graph_accepted = - ctx.graph.dispatch_step(ctx.graph.executor, graph_step); + runtime_ev.ctx.graph_accepted = graph.process_event(graph_step); } }; diff --git a/src/emel/speech/predictor/moshi/context.hpp b/src/emel/speech/predictor/moshi/context.hpp index 3daefbd6..5aedabee 100644 --- a/src/emel/speech/predictor/moshi/context.hpp +++ b/src/emel/speech/predictor/moshi/context.hpp @@ -17,13 +17,6 @@ inline constexpr int32_t k_max_delay_rows = 128; inline constexpr int32_t k_token_zero = -1; inline constexpr int32_t k_token_ungenerated = -2; -using graph_step_dispatch_fn = bool(void *, const event::graph_step &); - -struct graph_binding { - void *executor = nullptr; - graph_step_dispatch_fn *dispatch_step = nullptr; -}; - struct lmgen_state { int32_t codebook_count = 0; int32_t generated_dep_q = 0; @@ -66,25 +59,20 @@ struct voice_prompt_state { bool prompt_ready = false; }; +template struct dependencies { + emel::memory::hybrid::kv_binding kv_cache = {}; + graph_actor_type &graph; +}; + struct context { context() = default; explicit context(const emel::memory::hybrid::kv_binding &kv_cache) : memory(kv_cache) {} - context(const emel::memory::hybrid::kv_binding &kv_cache, - const graph_binding &graph_executor) - : graph(graph_executor), memory(kv_cache) {} runtime session = {}; voice_prompt_state voice = {}; - graph_binding graph = {}; lmgen_state lmgen = {}; emel::memory::hybrid::sm memory = {}; }; -inline graph_binding -bind_graph_executor(void *executor, - graph_step_dispatch_fn &dispatch_step) noexcept { - return graph_binding{.executor = executor, .dispatch_step = &dispatch_step}; -} - } // namespace emel::speech::predictor::moshi::action diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 8b928317..847aae8b 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -40,11 +40,26 @@ struct initialize { int32_t max_blocks = 4096; int32_t block_tokens = emel::memory::view::DEFAULT_BLOCK_TOKENS; int32_t sequence_id = 0; + bool sampling_enabled = false; + bool sampling_consume_forced_text = false; + float sampling_audio_temperature = 0.0f; + float sampling_text_temperature = 0.0f; + int32_t sampling_audio_top_k = 0; + int32_t sampling_text_top_k = 0; + uint32_t sampling_seed = 1u; emel::error::type *error_out = nullptr; emel::callback on_done = {}; emel::callback on_error = {}; }; +struct initialize_graph { + explicit initialize_graph(const initialize &request_ref) noexcept + : request(request_ref) {} + + const initialize &request; + emel::error::type *error_out = nullptr; +}; + struct load_voice { explicit load_voice(const emel::model::data &voice_model_ref) noexcept : voice_model(voice_model_ref) {} @@ -156,6 +171,8 @@ struct graph_step { struct initialize_ctx { emel::error::type err = emel::error::cast(error::none); + emel::error::type graph_error = emel::error::cast(error::none); + bool graph_accepted = false; bool memory_accepted = false; int32_t memory_error = static_cast(emel::error::cast(error::none)); }; diff --git a/src/emel/speech/predictor/moshi/executor/any.hpp b/src/emel/speech/predictor/moshi/executor/any.hpp index d80ec15f..4d79d34f 100644 --- a/src/emel/speech/predictor/moshi/executor/any.hpp +++ b/src/emel/speech/predictor/moshi/executor/any.hpp @@ -4,18 +4,6 @@ namespace emel::speech::predictor::moshi::executor { -inline bool dispatch_graph_step( - void *executor_ptr, - const emel::speech::predictor::moshi::event::graph_step &ev) noexcept { - return static_cast(executor_ptr)->process_event(ev); -} - -inline emel::speech::predictor::moshi::action::graph_binding -bind_graph_executor(sm &executor) noexcept { - return emel::speech::predictor::moshi::action::bind_graph_executor( - &executor, dispatch_graph_step); -} - using temporal_kv_binding = action::temporal_kv_binding; using depformer_kv_binding = action::depformer_kv_binding; using kv_bindings = action::kv_bindings; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 1f0bb880..26cd1e80 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -1016,6 +1016,21 @@ struct sm : public emel::sm { return accepted && ctx.err == action::detail_ns::to_error(error::none); } + bool process_event( + const emel::speech::predictor::moshi::event::initialize_graph &ev) { + event::initialize request{ev.request.model}; + request.sampling_enabled = ev.request.sampling_enabled; + request.sampling_consume_forced_text = + ev.request.sampling_consume_forced_text; + request.sampling_audio_temperature = ev.request.sampling_audio_temperature; + request.sampling_text_temperature = ev.request.sampling_text_temperature; + request.sampling_audio_top_k = ev.request.sampling_audio_top_k; + request.sampling_text_top_k = ev.request.sampling_text_top_k; + request.sampling_seed = ev.request.sampling_seed; + request.error_out = ev.error_out; + return process_event(request); + } + bool process_event(const emel::speech::predictor::moshi::event::graph_step &ev) { event::step_ctx ctx{}; diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index e221d6e3..7c90dd81 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -120,6 +120,22 @@ struct guard_memory_accepted { } }; +struct guard_graph_initialize_succeeded { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.graph_accepted && + runtime_ev.ctx.graph_error == + action::detail_ns::to_error(error::none); + } +}; + +struct guard_graph_initialize_failed { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_graph_initialize_succeeded{}(runtime_ev, ctx); + } +}; + struct guard_memory_rejected { template bool operator()(const runtime_event_type &runtime_ev, @@ -450,22 +466,6 @@ struct guard_no_voice_remaining_out { } }; -struct guard_graph_runtime_available { - template - bool operator()(const runtime_event_type &, - const action::context &ctx) const noexcept { - return ctx.graph.executor != nullptr && ctx.graph.dispatch_step != nullptr; - } -}; - -struct guard_graph_runtime_unavailable { - template - bool operator()(const runtime_event_type &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_graph_runtime_available{}(runtime_ev, ctx); - } -}; - struct guard_graph_step_accepted { template bool operator()(const runtime_event_type &runtime_ev, diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 975bb310..8a28b7d7 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -18,6 +18,8 @@ struct state_bind_contract_decision {}; struct state_binding {}; struct state_lmgen_mode_decision {}; struct state_configure_lmgen {}; +struct state_initialize_graph {}; +struct state_initialize_graph_decision {}; struct state_reserve_memory {}; struct state_reserve_memory_decision {}; struct state_allocate_sequence {}; @@ -103,7 +105,7 @@ struct state_uninit_begin_personaplex_prompt_callback_decision {}; struct state_uninit_prefill_personaplex_prompt_error_out_decision {}; struct state_uninit_prefill_personaplex_prompt_callback_decision {}; -struct model { +template struct model { auto operator()() const { namespace sml = stateforward::sml; using init_run = event::initialize_run; @@ -134,9 +136,18 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_standard_lmgen{} ] / action::effect_configure_standard_lmgen{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion + / action::effect_initialize_graph{} + , sml::state <= sml::state + + sml::completion + , sml::state <= sml::state + + sml::completion [ guard::guard_graph_initialize_succeeded{} ] / action::effect_reserve_memory{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_initialize_failed{} ] + / action::effect_mark_graph_runtime_error{} , sml::state <= sml::state + sml::completion , sml::state <= sml::state @@ -247,11 +258,8 @@ struct model { + sml::completion [ guard::guard_voice_embedding_frame_failed{} ] / action::effect_mark_voice_contract_error{} , sml::state <= sml::state - + sml::completion [ guard::guard_graph_runtime_available{} ] - / action::effect_run_voice_graph_runtime{} - , sml::state <= sml::state - + sml::completion [ guard::guard_graph_runtime_unavailable{} ] - / action::effect_mark_graph_runtime_unavailable{} + + sml::completion + / action::effect_run_voice_graph_runtime{} , sml::state <= sml::state + sml::completion , sml::state <= sml::state @@ -382,11 +390,8 @@ struct model { , sml::state <= sml::state + sml::completion , sml::state <= sml::state - + sml::completion [ guard::guard_graph_runtime_available{} ] - / action::effect_run_personaplex_prompt_graph_runtime{} - , sml::state <= sml::state - + sml::completion [ guard::guard_graph_runtime_unavailable{} ] - / action::effect_mark_graph_runtime_unavailable{} + + sml::completion + / action::effect_run_personaplex_prompt_graph_runtime{} , sml::state <= sml::state + sml::completion , sml::state <= sml::state @@ -505,11 +510,7 @@ struct model { sml::state + sml::completion , sml::state <= sml::state + sml::completion - [ guard::guard_graph_runtime_available{} ] / action::effect_run_sample_graph{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_graph_runtime_unavailable{} ] - / action::effect_mark_graph_runtime_unavailable{} + / action::effect_run_sample_graph{} , sml::state <= sml::state + sml::completion , sml::state <= @@ -640,18 +641,14 @@ struct model { } }; -struct sm : public emel::sm { - using base_type = emel::sm; +template +struct sm : public emel::sm, action::context> { + using base_type = emel::sm, action::context>; using base_type::is; using base_type::visit_current_states; - sm() : memory_snapshot_(std::make_unique()) {} - explicit sm(const emel::memory::hybrid::kv_binding &kv_cache) - : base_type(std::in_place, kv_cache), - memory_snapshot_(std::make_unique()) {} - sm(const emel::memory::hybrid::kv_binding &kv_cache, - const action::graph_binding &graph_executor) - : base_type(std::in_place, kv_cache, graph_executor), + explicit sm(const action::dependencies &deps) + : base_type(std::piecewise_construct, deps.kv_cache, deps.graph), memory_snapshot_(std::make_unique()) {} sm(const sm &) = delete; @@ -722,4 +719,7 @@ struct sm : public emel::sm { std::unique_ptr memory_snapshot_ = {}; }; +template +sm(const action::dependencies &) -> sm; + } // namespace emel::speech::predictor::moshi diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index 4b8ccfcb..73073b68 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -169,18 +169,6 @@ struct fake_decoder_actor { } }; -struct fake_runtime_actor { - int32_t initialize_calls = 0; - bool initialize_accepted = true; - emel::error::type initialize_error = 0; - - bool process_event(const fake_initialize &request) noexcept { - ++initialize_calls; - *request.error_out = initialize_error; - return initialize_accepted; - } -}; - struct fake_tokenizer_actor { int32_t initialize_calls = 0; int32_t tokenize_calls = 0; @@ -319,13 +307,11 @@ struct fake_dependencies { fake_encoder_actor &encoder; fake_tokenizer_actor &tokenizer; fake_decoder_actor &decoder; - fake_runtime_actor &runtime; fake_predictor_actor &predictor; fake_predictor_actor &sampler; fake_prediction_workspace &prediction_workspace; fake_initialize encoder_initialize = {}; fake_initialize decoder_initialize = {}; - fake_initialize runtime_initialize = {}; fake_initialize predictor_initialize = {}; fake_initialize conditioning_initialize = {}; std::span silence_pcm = {}; @@ -353,7 +339,6 @@ struct fixture { fake_encoder_actor encoder{}; fake_tokenizer_actor tokenizer{}; fake_decoder_actor decoder{}; - fake_runtime_actor runtime{}; fake_predictor_actor predictor{}; fake_prediction_workspace prediction_workspace{}; fake_dependencies dependencies; @@ -367,7 +352,6 @@ struct fixture { .encoder = encoder, .tokenizer = tokenizer, .decoder = decoder, - .runtime = runtime, .predictor = predictor, .sampler = predictor, .prediction_workspace = prediction_workspace, @@ -542,7 +526,6 @@ TEST_CASE("speech_generator_initializes_injected_actor_composition") { CHECK(test->machine.is(sml::state)); CHECK(test->encoder.initialize_calls == 1); CHECK(test->decoder.initialize_calls == 1); - CHECK(test->runtime.initialize_calls == 1); CHECK(test->predictor.initialize_calls == 2); } diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 2b442f95..58412572 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -40,6 +40,22 @@ struct recording_graph_executor { float first_embedding_sample = 0.0f; std::array first_input = {}; std::array last_input = {}; + + bool process_event(const moshi::event::initialize_graph &request) noexcept { + *request.error_out = k_no_error; + return true; + } + bool process_event(const moshi::event::graph_step &step); +}; + +struct rejecting_graph_executor { + bool process_event(const moshi::event::initialize_graph &request) noexcept { + *request.error_out = k_no_error; + return true; + } + bool process_event(const moshi::event::graph_step &) noexcept { + return false; + } }; struct temporal_kv_probe { @@ -161,9 +177,9 @@ struct moshi_callback_probe { } }; -bool dispatch_recording_graph(void *executor_ptr, - const moshi::event::graph_step &step) { - auto &executor = *static_cast(executor_ptr); +bool recording_graph_executor::process_event( + const moshi::event::graph_step &step) { + auto &executor = *this; ++executor.call_count; if (!step.input_embedding.empty()) { ++executor.external_embedding_count; @@ -279,7 +295,8 @@ void initialize_streaming_position(memory_streaming::sm &position) { } // namespace TEST_CASE("speech_moshi_predictor_rejects_predict_before_initialize") { - moshi::sm generator{}; + recording_graph_executor graph{}; + moshi::sm generator{moshi::action::dependencies{.graph = graph}}; std::array input = {0, 0, 0, 0}; moshi::event::predict::workspace workspace{}; emel::error::type err = k_no_error; @@ -294,7 +311,8 @@ TEST_CASE("speech_moshi_predictor_rejects_predict_before_initialize") { TEST_CASE("speech_moshi_generator_rejects_non_lm_model_contract") { auto model = std::make_unique(); model->moshi_component_id = emel::model::data::moshi_component::mimi; - moshi::sm generator{}; + recording_graph_executor graph{}; + moshi::sm generator{moshi::action::dependencies{.graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*model}; @@ -313,7 +331,9 @@ TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { emel::error::cast(emel::model::loader::error::none)); emel::memory::test::recording_kv_actor kv{}; - moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv)}; + recording_graph_executor graph{}; + moshi::sm generator{moshi::action::dependencies{ + .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -370,9 +390,8 @@ TEST_CASE( emel::memory::test::recording_kv_actor kv{}; recording_graph_executor graph{}; - moshi::sm generator{ - emel::memory::hybrid::bind_kv_actor(kv), - moshi::action::bind_graph_executor(&graph, dispatch_recording_graph)}; + moshi::sm generator{moshi::action::dependencies{ + .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -465,9 +484,8 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" emel::memory::test::recording_kv_actor kv{}; recording_graph_executor graph{}; - moshi::sm generator{ - emel::memory::hybrid::bind_kv_actor(kv), - moshi::action::bind_graph_executor(&graph, dispatch_recording_graph)}; + moshi::sm generator{moshi::action::dependencies{ + .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -584,9 +602,8 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" emel::memory::test::recording_kv_actor kv{}; recording_graph_executor graph{}; - moshi::sm generator{ - emel::memory::hybrid::bind_kv_actor(kv), - moshi::action::bind_graph_executor(&graph, dispatch_recording_graph)}; + moshi::sm generator{moshi::action::dependencies{ + .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -679,15 +696,16 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" CHECK(graph.call_count == prompt_frames + personaplex_prompt_frames + 1); } -TEST_CASE("speech_moshi_predictor_uses_memory_then_reports_missing_graph_" - "runtime") { +TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { return; } emel::memory::test::recording_kv_actor kv{}; - moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv)}; + rejecting_graph_executor graph{}; + moshi::sm generator{moshi::action::dependencies{ + .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; init.error_out = &err; @@ -715,7 +733,7 @@ TEST_CASE("speech_moshi_predictor_uses_memory_then_reports_missing_graph_" sample.error_out = &err; CHECK_FALSE(generator.process_event(sample)); - CHECK(err == emel::error::cast(moshi::error::graph_runtime_unavailable)); + CHECK(err == emel::error::cast(moshi::error::graph_runtime)); CHECK(kv.allocate_slots_count == 1); CHECK(kv.capture_view_count == 1); } @@ -1840,14 +1858,9 @@ TEST_CASE( emel::memory::test::recording_kv_actor kv{}; moshi_executor::sm executor{}; - emel::error::type executor_err = - emel::error::cast(moshi_executor::error::none); - moshi_executor::event::initialize executor_init{*fixture.model}; - executor_init.error_out = &executor_err; - REQUIRE(executor.process_event(executor_init)); - moshi::sm generator{emel::memory::hybrid::bind_kv_actor(kv), - moshi_executor::bind_graph_executor(executor)}; + moshi::sm generator{moshi::action::dependencies{ + .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = executor}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; init.error_out = &err; diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 25b5ff25..541ee738 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -111,13 +111,11 @@ struct personaplex_dependencies { mimi::sm &encoder; tokenizer::sm &tokenizer; mimi::sm &decoder; - runtime::sm &runtime; - predictor::sm &predictor; - predictor::sm &sampler; + predictor::sm &predictor; + predictor::sm &sampler; predictor::event::predict::workspace &prediction_workspace; mimi::event::initialize encoder_initialize; mimi::event::initialize decoder_initialize; - runtime::event::initialize runtime_initialize; predictor::event::initialize predictor_initialize; predictor::event::load_voice conditioning_initialize; std::span silence_pcm = {}; @@ -535,9 +533,10 @@ int main(int argc, char **argv) { runtime::bind_temporal_kv_cache(&cache_views, bind_temporal_cache), runtime::bind_depformer_kv_cache(&cache_views, bind_secondary_cache), temporal_positions, secondary_positions)}; - predictor::sm token_predictor{ - emel::memory::hybrid::kv_binding{}, - runtime::bind_graph_executor(prediction_runtime)}; + predictor::sm token_predictor{predictor::action::dependencies{ + .kv_cache = emel::memory::hybrid::kv_binding{}, + .graph = prediction_runtime, + }}; predictor::event::predict::workspace prediction_workspace{}; tokenizer::sm token_delay{tokenizer::dependencies{ .delays = std::span{delay_begin, delay_end}, @@ -556,17 +555,16 @@ int main(int argc, char **argv) { mimi::sm encoder{}; mimi::sm decoder{}; - runtime::event::initialize runtime_initialize{*lm_model.model}; - runtime_initialize.sampling_enabled = true; - runtime_initialize.sampling_consume_forced_text = true; - runtime_initialize.sampling_audio_temperature = config.audio_temperature; - runtime_initialize.sampling_text_temperature = config.text_temperature; - runtime_initialize.sampling_audio_top_k = config.audio_top_k; - runtime_initialize.sampling_text_top_k = config.text_top_k; - runtime_initialize.sampling_seed = config.sampling_seed; predictor::event::initialize predictor_initialize{*lm_model.model}; predictor_initialize.max_blocks = config.max_blocks; predictor_initialize.block_tokens = config.block_tokens; + predictor_initialize.sampling_enabled = true; + predictor_initialize.sampling_consume_forced_text = true; + predictor_initialize.sampling_audio_temperature = config.audio_temperature; + predictor_initialize.sampling_text_temperature = config.text_temperature; + predictor_initialize.sampling_audio_top_k = config.audio_top_k; + predictor_initialize.sampling_text_top_k = config.text_top_k; + predictor_initialize.sampling_seed = config.sampling_seed; personaplex_dependencies dependencies{ .temporal_positions = temporal_positions, @@ -574,7 +572,6 @@ int main(int argc, char **argv) { .encoder = encoder, .tokenizer = token_delay, .decoder = decoder, - .runtime = prediction_runtime, .predictor = token_predictor, .sampler = token_predictor, .prediction_workspace = prediction_workspace, @@ -590,7 +587,6 @@ int main(int argc, char **argv) { std::span{decoder_state}, std::span{decoder_workspace}, std::span{decoder_frame}}, - .runtime_initialize = runtime_initialize, .predictor_initialize = predictor_initialize, .conditioning_initialize = predictor::event::load_voice{*voice_model.model}, From cca8f0533351fa54274e52664479589a1bc55dc2 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 20:33:42 -0500 Subject: [PATCH 21/61] refactor: inject kernel into moshi executor --- .../speech/predictor/moshi/executor/any.hpp | 1 + .../predictor/moshi/executor/context.hpp | 19 ++--- .../speech/predictor/moshi/executor/sm.hpp | 7 +- .../moshi_executor_streaming_tests.cpp | 9 ++- .../predictor/moshi_lifecycle_tests.cpp | 71 +++++++++++++------ .../bench/speech/personaplex_emel_runner.cpp | 13 ++-- 6 files changed, 76 insertions(+), 44 deletions(-) diff --git a/src/emel/speech/predictor/moshi/executor/any.hpp b/src/emel/speech/predictor/moshi/executor/any.hpp index 4d79d34f..7bbea2a6 100644 --- a/src/emel/speech/predictor/moshi/executor/any.hpp +++ b/src/emel/speech/predictor/moshi/executor/any.hpp @@ -7,6 +7,7 @@ namespace emel::speech::predictor::moshi::executor { using temporal_kv_binding = action::temporal_kv_binding; using depformer_kv_binding = action::depformer_kv_binding; using kv_bindings = action::kv_bindings; +using dependencies = action::dependencies; inline temporal_kv_binding bind_temporal_kv_cache(void *cache, diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index c5aecd96..c16c3b07 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -36,6 +36,11 @@ struct kv_bindings { emel::memory::streaming::sm *depformer_positions = nullptr; }; +struct dependencies { + kv_bindings kv = {}; + emel::kernel::sm &kernel; +}; + struct runtime { const emel::model::data *model = nullptr; emel::model::moshi::detail::execution_contract contract = {}; @@ -57,14 +62,10 @@ struct sampling_config { }; struct context { - context() = default; - explicit context(const temporal_kv_binding &kv_binding) - : temporal_kv(kv_binding) {} - explicit context(const kv_bindings &kv_binding_set) - : temporal_kv(kv_binding_set.temporal), - depformer_kv(kv_binding_set.depformer), - temporal_positions(kv_binding_set.temporal_positions), - depformer_positions(kv_binding_set.depformer_positions) {} + explicit context(const dependencies &deps) + : temporal_kv(deps.kv.temporal), depformer_kv(deps.kv.depformer), + temporal_positions(deps.kv.temporal_positions), + depformer_positions(deps.kv.depformer_positions), kernel(deps.kernel) {} runtime session = {}; sampling_config sampling = {}; @@ -72,7 +73,7 @@ struct context { depformer_kv_binding depformer_kv = {}; emel::memory::streaming::sm *temporal_positions = nullptr; emel::memory::streaming::sm *depformer_positions = nullptr; - emel::kernel::sm kernel = {}; + emel::kernel::sm &kernel; }; inline temporal_kv_binding diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 26cd1e80..d323ba2f 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -1003,11 +1003,8 @@ struct sm : public emel::sm { using base_type::is; using base_type::visit_current_states; - sm() = default; - explicit sm(const action::temporal_kv_binding &kv_binding) - : base_type(std::in_place, kv_binding) {} - explicit sm(const action::kv_bindings &kv_binding_set) - : base_type(std::in_place, kv_binding_set) {} + explicit sm(const action::dependencies &deps) + : base_type(std::in_place, deps) {} bool process_event(const event::initialize &ev) { event::initialize_ctx ctx{}; diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index ec07b963..e13a9b5b 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -107,9 +107,12 @@ TEST_CASE( executor::bind_temporal_kv_cache(&temporal_cache, bind_temporal_cache); const auto depformer_binding = executor::bind_depformer_kv_cache(&depformer_cache, bind_depformer_cache); - executor::sm machine{ - executor::bind_kv_caches(temporal_binding, depformer_binding, - temporal_positions, depformer_positions)}; + emel::kernel::sm kernel{}; + executor::sm machine{executor::dependencies{ + .kv = executor::bind_kv_caches(temporal_binding, depformer_binding, + temporal_positions, depformer_positions), + .kernel = kernel, + }}; emel::error::type err = emel::error::cast(executor::error::none); executor::event::initialize initialize{*fixture.model}; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 58412572..3db66d91 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -744,7 +744,8 @@ TEST_CASE("speech_moshi_executor_initializes_lm_fixture") { return; } - moshi_executor::sm executor{}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -759,7 +760,8 @@ TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { return; } - moshi_executor::sm executor{}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.sampling_enabled = true; @@ -807,7 +809,8 @@ TEST_CASE("speech_moshi_executor_rejects_graph_step_before_initialize") { return; } - moshi_executor::sm executor{}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; std::array input = {0, 1, 2, 3}; std::array output = {}; int32_t text_token = -1; @@ -1277,7 +1280,9 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { std::span{embedding.data(), static_cast(lm.dim)}; moshi_executor::event::step_ctx step_ctx{}; moshi_executor::event::step_run step_run{step, step_ctx}; - moshi_executor::action::context executor_ctx{}; + emel::kernel::sm guard_kernel{}; + moshi_executor::action::context executor_ctx{ + moshi_executor::dependencies{.kernel = guard_kernel}}; executor_ctx.session.model = fixture.model.get(); executor_ctx.session.codebook_count = lm.n_q + 1; executor_ctx.session.dep_q = lm.dep_q; @@ -1492,7 +1497,8 @@ TEST_CASE("speech_moshi_executor_embeds_input_before_unsupported_transformer") { return; } - moshi_executor::sm executor{}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1537,7 +1543,9 @@ TEST_CASE( &probe, temporal_kv_probe_bind), .temporal_positions = &temporal_positions, }; - moshi_executor::sm executor{bindings}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{ + moshi_executor::dependencies{.kv = bindings, .kernel = kernel}}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1624,8 +1632,12 @@ TEST_CASE("speech_moshi_executor_accepts_personaplex_voice_embedding_step") { .capacity = fixture.model->moshi_lm.depformer_context}}; initialize_streaming_position(temporal_positions); initialize_streaming_position(depformer_positions); - moshi_executor::sm executor{moshi_executor::bind_kv_caches( - temporal_kv, depformer_kv, temporal_positions, depformer_positions)}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{moshi_executor::dependencies{ + .kv = moshi_executor::bind_kv_caches( + temporal_kv, depformer_kv, temporal_positions, depformer_positions), + .kernel = kernel, + }}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1690,8 +1702,12 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { .capacity = fixture.model->moshi_lm.depformer_context}}; initialize_streaming_position(temporal_positions); initialize_streaming_position(depformer_positions); - moshi_executor::sm executor{moshi_executor::bind_kv_caches( - temporal_kv, depformer_kv, temporal_positions, depformer_positions)}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{moshi_executor::dependencies{ + .kv = moshi_executor::bind_kv_caches( + temporal_kv, depformer_kv, temporal_positions, depformer_positions), + .kernel = kernel, + }}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1782,18 +1798,26 @@ TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { initialize_streaming_position(first_depformer_positions); initialize_streaming_position(second_temporal_positions); initialize_streaming_position(second_depformer_positions); - moshi_executor::sm first{moshi_executor::bind_kv_caches( - moshi_executor::bind_temporal_kv_cache(&first_temporal, - temporal_kv_probe_bind), - moshi_executor::bind_depformer_kv_cache(&first_depformer, - depformer_kv_probe_bind), - first_temporal_positions, first_depformer_positions)}; - moshi_executor::sm second{moshi_executor::bind_kv_caches( - moshi_executor::bind_temporal_kv_cache(&second_temporal, - temporal_kv_probe_bind), - moshi_executor::bind_depformer_kv_cache(&second_depformer, - depformer_kv_probe_bind), - second_temporal_positions, second_depformer_positions)}; + emel::kernel::sm first_kernel{}; + emel::kernel::sm second_kernel{}; + moshi_executor::sm first{moshi_executor::dependencies{ + .kv = moshi_executor::bind_kv_caches( + moshi_executor::bind_temporal_kv_cache(&first_temporal, + temporal_kv_probe_bind), + moshi_executor::bind_depformer_kv_cache(&first_depformer, + depformer_kv_probe_bind), + first_temporal_positions, first_depformer_positions), + .kernel = first_kernel, + }}; + moshi_executor::sm second{moshi_executor::dependencies{ + .kv = moshi_executor::bind_kv_caches( + moshi_executor::bind_temporal_kv_cache(&second_temporal, + temporal_kv_probe_bind), + moshi_executor::bind_depformer_kv_cache(&second_depformer, + depformer_kv_probe_bind), + second_temporal_positions, second_depformer_positions), + .kernel = second_kernel, + }}; emel::error::type first_err = emel::error::cast(moshi_executor::error::none); emel::error::type second_err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize first_init{*first_fixture.model}; @@ -1857,7 +1881,8 @@ TEST_CASE( } emel::memory::test::recording_kv_actor kv{}; - moshi_executor::sm executor{}; + emel::kernel::sm kernel{}; + moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; moshi::sm generator{moshi::action::dependencies{ .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = executor}}; diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 541ee738..a56f3959 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -17,6 +17,7 @@ #include "emel/gguf/loader/detail.hpp" #include "emel/gguf/loader/events.hpp" #include "emel/gguf/loader/sm.hpp" +#include "emel/kernel/sm.hpp" #include "emel/memory/streaming/sm.hpp" #include "emel/model/data.hpp" #include "emel/model/detail.hpp" @@ -529,10 +530,14 @@ int main(int argc, char **argv) { .kv_dim = lm_model.model->moshi_lm.depformer_dim, }, }; - runtime::sm prediction_runtime{runtime::bind_kv_caches( - runtime::bind_temporal_kv_cache(&cache_views, bind_temporal_cache), - runtime::bind_depformer_kv_cache(&cache_views, bind_secondary_cache), - temporal_positions, secondary_positions)}; + emel::kernel::sm prediction_kernel{}; + runtime::sm prediction_runtime{runtime::dependencies{ + .kv = runtime::bind_kv_caches( + runtime::bind_temporal_kv_cache(&cache_views, bind_temporal_cache), + runtime::bind_depformer_kv_cache(&cache_views, bind_secondary_cache), + temporal_positions, secondary_positions), + .kernel = prediction_kernel, + }}; predictor::sm token_predictor{predictor::action::dependencies{ .kv_cache = emel::memory::hybrid::kv_binding{}, .graph = prediction_runtime, From 673050a17efbd53ad47b091965c20b47dd1d95f7 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 20:40:30 -0500 Subject: [PATCH 22/61] refactor: inject moshi numeric policy --- .../predictor/moshi/executor/actions.hpp | 13 ++- .../predictor/moshi/executor/context.hpp | 10 +- .../predictor/moshi/executor/detail.hpp | 1 - .../predictor/moshi/executor/guards.hpp | 5 +- .../moshi_executor_streaming_tests.cpp | 4 + .../predictor/moshi_lifecycle_tests.cpp | 95 ++++++++++++------- .../bench/speech/personaplex_emel_runner.cpp | 4 + 7 files changed, 85 insertions(+), 47 deletions(-) diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 1e8eacb3..c65f9698 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -52,8 +52,7 @@ struct effect_bind_nonzero_sampling_seed { struct effect_bind_zero_sampling_seed { void operator()(const event::initialize_run &, context &ctx) const noexcept { - constexpr uint32_t zero_seed_state = 123459876u; - ctx.sampling.random_state = zero_seed_state; + ctx.sampling.random_state = ctx.policy.zero_seed_state; } }; @@ -356,7 +355,7 @@ struct effect_run_temporal_layer_norm_rms { .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), static_cast(hidden_dim)), }; - detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + detail::set_op_param_f32(rms_ev, 0u, ctx.policy.rms_norm_epsilon); runtime_ev.ctx.temporal_layer_norm_rms_ok = ctx.kernel.process_event(rms_ev); } @@ -674,7 +673,7 @@ struct effect_run_temporal_layer_norm2_rms { .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), static_cast(hidden_dim)), }; - detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + detail::set_op_param_f32(rms_ev, 0u, ctx.policy.rms_norm_epsilon); runtime_ev.ctx.temporal_layer_norm2_rms_ok = ctx.kernel.process_event(rms_ev); } @@ -892,7 +891,7 @@ struct effect_run_temporal_out_norm_rms { .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), static_cast(hidden_dim)), }; - detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + detail::set_op_param_f32(rms_ev, 0u, ctx.policy.rms_norm_epsilon); runtime_ev.ctx.temporal_out_norm_rms_ok = ctx.kernel.process_event(rms_ev); } }; @@ -1254,7 +1253,7 @@ struct effect_run_depformer_layer_norm_rms { .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), static_cast(dep_dim)), }; - detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + detail::set_op_param_f32(rms_ev, 0u, ctx.policy.rms_norm_epsilon); runtime_ev.ctx.depformer_layer_norm_rms_ok = ctx.kernel.process_event(rms_ev); } @@ -1496,7 +1495,7 @@ struct effect_run_depformer_layer_norm2_rms { .dst = detail::make_f32_dst(runtime_ev.ctx.row.data(), static_cast(dep_dim)), }; - detail::set_op_param_f32(rms_ev, 0u, detail::k_rms_norm_eps); + detail::set_op_param_f32(rms_ev, 0u, ctx.policy.rms_norm_epsilon); runtime_ev.ctx.depformer_layer_norm2_rms_ok = ctx.kernel.process_event(rms_ev); } diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index c16c3b07..ad80f013 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -36,9 +36,15 @@ struct kv_bindings { emel::memory::streaming::sm *depformer_positions = nullptr; }; +struct policies { + float rms_norm_epsilon = 0.0f; + uint32_t zero_seed_state = 0u; +}; + struct dependencies { kv_bindings kv = {}; emel::kernel::sm &kernel; + policies policy = {}; }; struct runtime { @@ -65,7 +71,8 @@ struct context { explicit context(const dependencies &deps) : temporal_kv(deps.kv.temporal), depformer_kv(deps.kv.depformer), temporal_positions(deps.kv.temporal_positions), - depformer_positions(deps.kv.depformer_positions), kernel(deps.kernel) {} + depformer_positions(deps.kv.depformer_positions), kernel(deps.kernel), + policy(deps.policy) {} runtime session = {}; sampling_config sampling = {}; @@ -74,6 +81,7 @@ struct context { emel::memory::streaming::sm *temporal_positions = nullptr; emel::memory::streaming::sm *depformer_positions = nullptr; emel::kernel::sm &kernel; + const policies policy; }; inline temporal_kv_binding diff --git a/src/emel/speech/predictor/moshi/executor/detail.hpp b/src/emel/speech/predictor/moshi/executor/detail.hpp index 10b77aa9..4f9010b5 100644 --- a/src/emel/speech/predictor/moshi/executor/detail.hpp +++ b/src/emel/speech/predictor/moshi/executor/detail.hpp @@ -30,7 +30,6 @@ inline constexpr uint64_t k_max_depformer_context = 512u; inline constexpr uint64_t k_max_sampling_card = 65536u; inline constexpr uint64_t k_max_sampling_top_k = 1024u; inline constexpr int32_t k_token_zero = -1; -inline constexpr float k_rms_norm_eps = 1.0e-8f; struct streaming_kv_view { std::span key_cache = {}; diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index e2b7e850..ff5e771c 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -12,7 +12,7 @@ namespace emel::speech::predictor::moshi::executor::guard { struct guard_bind_contract_valid { bool operator()(const event::initialize_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; return emel::model::moshi::detail::validate_execution_contract(model) == emel::error::cast(emel::model::loader::error::none) && @@ -20,7 +20,8 @@ struct guard_bind_contract_valid { model.moshi_lm.n_q > 0 && model.moshi_lm.dep_q > 0 && model.moshi_lm.dep_q <= model.moshi_lm.n_q && model.moshi_lm.text_card > 0 && model.moshi_lm.card > 0 && - model.moshi_lm.dim > 0; + model.moshi_lm.dim > 0 && ctx.policy.rms_norm_epsilon > 0.0f && + ctx.policy.zero_seed_state != 0u; } }; diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index e13a9b5b..e3605e33 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -112,6 +112,10 @@ TEST_CASE( .kv = executor::bind_kv_caches(temporal_binding, depformer_binding, temporal_positions, depformer_positions), .kernel = kernel, + .policy = executor::action::policies{ + .rms_norm_epsilon = 1.0e-8f, + .zero_seed_state = 123459876u, + }, }}; emel::error::type err = emel::error::cast(executor::error::none); diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 3db66d91..0b4359e1 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -29,6 +29,19 @@ using emel::speech::predictor::moshi::test::repo_root; inline constexpr emel::error::type k_no_error = emel::error::cast(moshi::error::none); +moshi_executor::dependencies make_executor_dependencies( + emel::kernel::sm &kernel, + const moshi_executor::kv_bindings &kv = {}) noexcept { + return moshi_executor::dependencies{ + .kv = kv, + .kernel = kernel, + .policy = moshi_executor::action::policies{ + .rms_norm_epsilon = 1.0e-8f, + .zero_seed_state = 123459876u, + }, + }; +} + struct recording_graph_executor { int32_t call_count = 0; int32_t external_embedding_count = 0; @@ -745,7 +758,7 @@ TEST_CASE("speech_moshi_executor_initializes_lm_fixture") { } emel::kernel::sm kernel{}; - moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; + moshi_executor::sm executor{make_executor_dependencies(kernel)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -754,6 +767,23 @@ TEST_CASE("speech_moshi_executor_initializes_lm_fixture") { CHECK(err == emel::error::cast(moshi_executor::error::none)); } +TEST_CASE("speech_moshi_executor_rejects_missing_numeric_policy") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::kernel::sm kernel{}; + moshi_executor::sm executor{ + moshi_executor::dependencies{.kernel = kernel}}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + + CHECK_FALSE(executor.process_event(init)); + CHECK(err == emel::error::cast(moshi_executor::error::bind_failed)); +} + TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { @@ -761,7 +791,7 @@ TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { } emel::kernel::sm kernel{}; - moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; + moshi_executor::sm executor{make_executor_dependencies(kernel)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.sampling_enabled = true; @@ -810,7 +840,7 @@ TEST_CASE("speech_moshi_executor_rejects_graph_step_before_initialize") { } emel::kernel::sm kernel{}; - moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; + moshi_executor::sm executor{make_executor_dependencies(kernel)}; std::array input = {0, 1, 2, 3}; std::array output = {}; int32_t text_token = -1; @@ -1282,7 +1312,7 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { moshi_executor::event::step_run step_run{step, step_ctx}; emel::kernel::sm guard_kernel{}; moshi_executor::action::context executor_ctx{ - moshi_executor::dependencies{.kernel = guard_kernel}}; + make_executor_dependencies(guard_kernel)}; executor_ctx.session.model = fixture.model.get(); executor_ctx.session.codebook_count = lm.n_q + 1; executor_ctx.session.dep_q = lm.dep_q; @@ -1498,7 +1528,7 @@ TEST_CASE("speech_moshi_executor_embeds_input_before_unsupported_transformer") { } emel::kernel::sm kernel{}; - moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; + moshi_executor::sm executor{make_executor_dependencies(kernel)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1544,8 +1574,7 @@ TEST_CASE( .temporal_positions = &temporal_positions, }; emel::kernel::sm kernel{}; - moshi_executor::sm executor{ - moshi_executor::dependencies{.kv = bindings, .kernel = kernel}}; + moshi_executor::sm executor{make_executor_dependencies(kernel, bindings)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1633,11 +1662,9 @@ TEST_CASE("speech_moshi_executor_accepts_personaplex_voice_embedding_step") { initialize_streaming_position(temporal_positions); initialize_streaming_position(depformer_positions); emel::kernel::sm kernel{}; - moshi_executor::sm executor{moshi_executor::dependencies{ - .kv = moshi_executor::bind_kv_caches( - temporal_kv, depformer_kv, temporal_positions, depformer_positions), - .kernel = kernel, - }}; + const auto bindings = moshi_executor::bind_kv_caches( + temporal_kv, depformer_kv, temporal_positions, depformer_positions); + moshi_executor::sm executor{make_executor_dependencies(kernel, bindings)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1703,11 +1730,9 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { initialize_streaming_position(temporal_positions); initialize_streaming_position(depformer_positions); emel::kernel::sm kernel{}; - moshi_executor::sm executor{moshi_executor::dependencies{ - .kv = moshi_executor::bind_kv_caches( - temporal_kv, depformer_kv, temporal_positions, depformer_positions), - .kernel = kernel, - }}; + const auto bindings = moshi_executor::bind_kv_caches( + temporal_kv, depformer_kv, temporal_positions, depformer_positions); + moshi_executor::sm executor{make_executor_dependencies(kernel, bindings)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1800,24 +1825,22 @@ TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { initialize_streaming_position(second_depformer_positions); emel::kernel::sm first_kernel{}; emel::kernel::sm second_kernel{}; - moshi_executor::sm first{moshi_executor::dependencies{ - .kv = moshi_executor::bind_kv_caches( - moshi_executor::bind_temporal_kv_cache(&first_temporal, - temporal_kv_probe_bind), - moshi_executor::bind_depformer_kv_cache(&first_depformer, - depformer_kv_probe_bind), - first_temporal_positions, first_depformer_positions), - .kernel = first_kernel, - }}; - moshi_executor::sm second{moshi_executor::dependencies{ - .kv = moshi_executor::bind_kv_caches( - moshi_executor::bind_temporal_kv_cache(&second_temporal, - temporal_kv_probe_bind), - moshi_executor::bind_depformer_kv_cache(&second_depformer, - depformer_kv_probe_bind), - second_temporal_positions, second_depformer_positions), - .kernel = second_kernel, - }}; + const auto first_bindings = moshi_executor::bind_kv_caches( + moshi_executor::bind_temporal_kv_cache(&first_temporal, + temporal_kv_probe_bind), + moshi_executor::bind_depformer_kv_cache(&first_depformer, + depformer_kv_probe_bind), + first_temporal_positions, first_depformer_positions); + const auto second_bindings = moshi_executor::bind_kv_caches( + moshi_executor::bind_temporal_kv_cache(&second_temporal, + temporal_kv_probe_bind), + moshi_executor::bind_depformer_kv_cache(&second_depformer, + depformer_kv_probe_bind), + second_temporal_positions, second_depformer_positions); + moshi_executor::sm first{ + make_executor_dependencies(first_kernel, first_bindings)}; + moshi_executor::sm second{ + make_executor_dependencies(second_kernel, second_bindings)}; emel::error::type first_err = emel::error::cast(moshi_executor::error::none); emel::error::type second_err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize first_init{*first_fixture.model}; @@ -1882,7 +1905,7 @@ TEST_CASE( emel::memory::test::recording_kv_actor kv{}; emel::kernel::sm kernel{}; - moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; + moshi_executor::sm executor{make_executor_dependencies(kernel)}; moshi::sm generator{moshi::action::dependencies{ .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = executor}}; diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index a56f3959..a00a9eda 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -537,6 +537,10 @@ int main(int argc, char **argv) { runtime::bind_depformer_kv_cache(&cache_views, bind_secondary_cache), temporal_positions, secondary_positions), .kernel = prediction_kernel, + .policy = runtime::action::policies{ + .rms_norm_epsilon = 1.0e-8f, + .zero_seed_state = 123459876u, + }, }}; predictor::sm token_predictor{predictor::action::dependencies{ .kv_cache = emel::memory::hybrid::kv_binding{}, From dc2d61a1b443bc3edb70dfe84ebc39efcec25c40 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 20:47:01 -0500 Subject: [PATCH 23/61] refactor: inject moshi executor capacities --- .../predictor/moshi/executor/context.hpp | 12 ++- .../predictor/moshi/executor/guards.hpp | 83 +++++++++++-------- .../moshi_executor_streaming_tests.cpp | 7 ++ .../predictor/moshi_lifecycle_tests.cpp | 25 ++++++ .../bench/speech/personaplex_emel_runner.cpp | 14 ++++ 5 files changed, 104 insertions(+), 37 deletions(-) diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index ad80f013..489b88c5 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -41,10 +41,19 @@ struct policies { uint32_t zero_seed_state = 0u; }; +struct capacities { + uint64_t hidden_dim = 0u; + uint64_t temporal_context = 0u; + uint64_t depformer_context = 0u; + uint64_t sampling_card = 0u; + uint64_t sampling_top_k = 0u; +}; + struct dependencies { kv_bindings kv = {}; emel::kernel::sm &kernel; policies policy = {}; + capacities capacity = {}; }; struct runtime { @@ -72,7 +81,7 @@ struct context { : temporal_kv(deps.kv.temporal), depformer_kv(deps.kv.depformer), temporal_positions(deps.kv.temporal_positions), depformer_positions(deps.kv.depformer_positions), kernel(deps.kernel), - policy(deps.policy) {} + policy(deps.policy), capacity(deps.capacity) {} runtime session = {}; sampling_config sampling = {}; @@ -82,6 +91,7 @@ struct context { emel::memory::streaming::sm *depformer_positions = nullptr; emel::kernel::sm &kernel; const policies policy; + const capacities capacity; }; inline temporal_kv_binding diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index ff5e771c..dc38f1d4 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -21,7 +21,16 @@ struct guard_bind_contract_valid { model.moshi_lm.dep_q <= model.moshi_lm.n_q && model.moshi_lm.text_card > 0 && model.moshi_lm.card > 0 && model.moshi_lm.dim > 0 && ctx.policy.rms_norm_epsilon > 0.0f && - ctx.policy.zero_seed_state != 0u; + ctx.policy.zero_seed_state != 0u && ctx.capacity.hidden_dim > 0u && + ctx.capacity.hidden_dim <= detail::k_max_hidden_dim && + ctx.capacity.temporal_context > 0u && + ctx.capacity.temporal_context <= detail::k_max_temporal_context && + ctx.capacity.depformer_context > 0u && + ctx.capacity.depformer_context <= detail::k_max_depformer_context && + ctx.capacity.sampling_card > 0u && + ctx.capacity.sampling_card <= detail::k_max_sampling_card && + ctx.capacity.sampling_top_k > 0u && + ctx.capacity.sampling_top_k <= detail::k_max_sampling_top_k; } }; @@ -119,7 +128,7 @@ struct guard_external_input_embedding_supported { static_cast(ctx.session.hidden_dim) && ctx.session.hidden_dim > 0 && static_cast(ctx.session.hidden_dim) <= - detail::k_max_hidden_dim; + ctx.capacity.hidden_dim; } }; @@ -157,7 +166,7 @@ struct guard_token_input_embedding_supported { } return runtime_ev.request.input_embedding.data() == nullptr && !lm.demux_second_stream && hidden_dim > 0 && - static_cast(hidden_dim) <= detail::k_max_hidden_dim && + static_cast(hidden_dim) <= ctx.capacity.hidden_dim && root_tensors_ok && audio_tensors_ok && tokens_ok; } }; @@ -391,7 +400,7 @@ struct guard_temporal_layer_norm_supported { const auto *norm1 = detail::find_lm_transformer_tensor(model, layer, "norm1.alpha"); return layer >= 0 && layer < model.moshi_lm.num_layers && hidden_dim > 0 && - static_cast(hidden_dim) <= detail::k_max_hidden_dim && + static_cast(hidden_dim) <= ctx.capacity.hidden_dim && detail::tensor_shape(norm1, hidden_dim) && static_cast(norm1->type) == detail::dtype::f32; } @@ -441,8 +450,9 @@ struct guard_temporal_layer_projection_supported { const auto *projection = detail::find_lm_transformer_projection(model, layer); return layer >= 0 && layer < model.moshi_lm.num_layers && hidden_dim > 0 && - static_cast(hidden_dim) <= detail::k_max_hidden_dim && - static_cast(hidden_dim) * 3u <= detail::k_max_qkv_dim && + static_cast(hidden_dim) <= ctx.capacity.hidden_dim && + static_cast(hidden_dim) * 3u <= + ctx.capacity.hidden_dim * 3u && detail::tensor_shape(projection, hidden_dim, hidden_dim * 3) && detail::supported_mul_mat_dtype( static_cast(projection->type)); @@ -481,7 +491,7 @@ struct guard_temporal_layer_rope_supported { lm.num_heads > 0 && lm.max_period > 0 && hidden_dim % lm.num_heads == 0 && head_dim > 0 && (head_dim % 2) == 0 && - static_cast(head_dim) <= detail::k_max_hidden_dim && + static_cast(head_dim) <= ctx.capacity.hidden_dim && position.logical_position >= 0 && position.logical_position <= std::numeric_limits::max() && position.physical_position >= 0 && @@ -569,9 +579,9 @@ struct guard_temporal_layer_attention_supported { const int32_t layer = runtime_ev.ctx.temporal_layer_index; if (!runtime_ev.ctx.temporal_layer_cache_write_ok || hidden_dim <= 0 || lm.num_heads <= 0 || hidden_dim % lm.num_heads != 0 || head_dim <= 0 || - static_cast(head_dim) > detail::k_max_hidden_dim || + static_cast(head_dim) > ctx.capacity.hidden_dim || window.valid_positions <= 0 || capacity <= 0 || - static_cast(capacity) > detail::k_max_temporal_context || + static_cast(capacity) > ctx.capacity.temporal_context || window.capacity != capacity || window.valid_positions > capacity || window.logical_begin < 0 || window.logical_end - window.logical_begin != window.valid_positions || @@ -671,7 +681,7 @@ struct guard_temporal_layer_norm2_supported { detail::find_lm_transformer_tensor(model, layer, "norm2.alpha"); return runtime_ev.ctx.temporal_layer_residual_ok && layer >= 0 && layer < model.moshi_lm.num_layers && hidden_dim > 0 && - static_cast(hidden_dim) <= detail::k_max_hidden_dim && + static_cast(hidden_dim) <= ctx.capacity.hidden_dim && detail::tensor_shape(norm2, hidden_dim) && static_cast(norm2->type) == detail::dtype::f32; } @@ -727,7 +737,7 @@ struct guard_temporal_layer_gating_in_supported { layer < runtime_ev.request.model.moshi_lm.num_layers && hidden_dim > 0 && projection_dim > 0 && (projection_dim % 2) == 0 && static_cast(projection_dim) <= - detail::k_max_gating_projection_dim && + ctx.capacity.hidden_dim * 8u && detail::tensor_shape(linear_in, hidden_dim, projection_dim) && detail::supported_mul_mat_dtype( static_cast(linear_in->type)); @@ -757,7 +767,7 @@ struct guard_temporal_layer_gating_in_failed { struct guard_temporal_layer_silu_gate_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto *linear_in = detail::find_lm_transformer_tensor( runtime_ev.request.model, runtime_ev.ctx.temporal_layer_index, "gating.linear_in.weight"); @@ -771,7 +781,7 @@ struct guard_temporal_layer_silu_gate_supported { runtime_ev.ctx.temporal_layer_index < runtime_ev.request.model.moshi_lm.num_layers && gate_dim > 0 && - static_cast(gate_dim) <= detail::k_max_gating_dim; + static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u; } }; @@ -827,7 +837,7 @@ struct guard_temporal_layer_gating_out_supported { return runtime_ev.ctx.temporal_layer_silu_gate_ok && layer >= 0 && layer < runtime_ev.request.model.moshi_lm.num_layers && hidden_dim > 0 && gate_dim > 0 && - static_cast(gate_dim) <= detail::k_max_gating_dim && + static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u && detail::tensor_shape(linear_out, gate_dim, hidden_dim) && detail::supported_mul_mat_dtype( static_cast(linear_out->type)); @@ -894,7 +904,7 @@ struct guard_temporal_out_norm_supported { detail::find_tensor(runtime_ev.request.model, "lm.out_norm.alpha"); return guard_temporal_layers_complete{}(runtime_ev, ctx) && hidden_dim > 0 && - static_cast(hidden_dim) <= detail::k_max_hidden_dim && + static_cast(hidden_dim) <= ctx.capacity.hidden_dim && detail::tensor_shape(out_norm, hidden_dim) && static_cast(out_norm->type) == detail::dtype::f32; } @@ -981,9 +991,9 @@ struct guard_text_sampling_config_valid { ctx.sampling.text_top_k > 0 && ctx.sampling.text_top_k <= ctx.session.text_card && static_cast(ctx.session.text_card) <= - detail::k_max_sampling_card && + ctx.capacity.sampling_card && static_cast(ctx.sampling.text_top_k) <= - detail::k_max_sampling_top_k; + ctx.capacity.sampling_top_k; } }; @@ -1244,7 +1254,7 @@ struct guard_depformer_text_input_supported { detail::find_tensor(model, "lm.depformer_text_emb.weight"); return runtime_ev.ctx.depformer_kv_bound && runtime_ev.ctx.text_logits_ok && codebook == 0 && hidden_dim > 0 && dep_dim > 0 && - static_cast(dep_dim) <= detail::k_max_hidden_dim && + static_cast(dep_dim) <= ctx.capacity.hidden_dim && detail::tensor_shape(input_projection, hidden_dim, dep_dim) && detail::supported_mul_mat_dtype( static_cast(input_projection->type)) && @@ -1278,7 +1288,7 @@ struct guard_depformer_audio_input_supported { return runtime_ev.ctx.depformer_kv_bound && runtime_ev.ctx.text_logits_ok && codebook > 0 && codebook < lm.dep_q && hidden_dim > 0 && dep_dim > 0 && - static_cast(dep_dim) <= detail::k_max_hidden_dim && + static_cast(dep_dim) <= ctx.capacity.hidden_dim && detail::tensor_shape(input_projection, hidden_dim, dep_dim) && detail::supported_mul_mat_dtype( static_cast(input_projection->type)) && @@ -1369,7 +1379,7 @@ struct guard_depformer_input_projection_embedding_unsupported { struct guard_depformer_layer_norm_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const int32_t dep_dim = model.moshi_lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; @@ -1377,7 +1387,7 @@ struct guard_depformer_layer_norm_supported { detail::find_depformer_tensor(model, layer, "norm1.alpha"); return runtime_ev.ctx.depformer_input_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && dep_dim > 0 && - static_cast(dep_dim) <= detail::k_max_hidden_dim && + static_cast(dep_dim) <= ctx.capacity.hidden_dim && detail::tensor_shape(norm1, dep_dim) && static_cast(norm1->type) == detail::dtype::f32; } @@ -1420,7 +1430,7 @@ struct guard_depformer_layer_norm_failed { struct guard_depformer_layer_projection_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; const int32_t dep_dim = model.moshi_lm.depformer_dim; @@ -1435,7 +1445,8 @@ struct guard_depformer_layer_projection_supported { return runtime_ev.ctx.depformer_layer_norm_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && codebook < model.moshi_lm.dep_q && dep_dim > 0 && - static_cast(dep_dim) * 3u <= detail::k_max_qkv_dim && + static_cast(dep_dim) * 3u <= + ctx.capacity.hidden_dim * 3u && detail::tensor_shape(projection, dep_dim, dep_dim * 3) && detail::supported_mul_mat_dtype( static_cast(projection->type)); @@ -1511,7 +1522,7 @@ struct guard_depformer_layer_cache_write_failed { struct guard_depformer_layer_attention_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; const auto &view = runtime_ev.ctx.depformer_kv; const int32_t dep_dim = lm.depformer_dim; @@ -1524,9 +1535,9 @@ struct guard_depformer_layer_attention_supported { if (!runtime_ev.ctx.depformer_layer_cache_write_ok || dep_dim <= 0 || lm.depformer_num_heads <= 0 || dep_dim % lm.depformer_num_heads != 0 || head_dim <= 0 || - static_cast(head_dim) > detail::k_max_hidden_dim || + static_cast(head_dim) > ctx.capacity.hidden_dim || valid_positions <= 0 || capacity <= 0 || - static_cast(capacity) > detail::k_max_depformer_context || + static_cast(capacity) > ctx.capacity.depformer_context || valid_positions > capacity || window.capacity != capacity || window.logical_begin < 0 || window.logical_end - window.logical_begin != valid_positions || @@ -1631,7 +1642,7 @@ struct guard_depformer_layer_residual_failed { struct guard_depformer_layer_norm2_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const int32_t dep_dim = model.moshi_lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; @@ -1639,7 +1650,7 @@ struct guard_depformer_layer_norm2_supported { detail::find_depformer_tensor(model, layer, "norm2.alpha"); return runtime_ev.ctx.depformer_layer_residual_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && dep_dim > 0 && - static_cast(dep_dim) <= detail::k_max_hidden_dim && + static_cast(dep_dim) <= ctx.capacity.hidden_dim && detail::tensor_shape(norm2, dep_dim) && static_cast(norm2->type) == detail::dtype::f32; } @@ -1682,7 +1693,7 @@ struct guard_depformer_layer_norm2_failed { struct guard_depformer_layer_gating_in_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; @@ -1703,7 +1714,7 @@ struct guard_depformer_layer_gating_in_supported { codebook < model.moshi_lm.dep_q && dep_dim > 0 && projection_dim > 0 && (projection_dim % 2) == 0 && static_cast(projection_dim) <= - detail::k_max_gating_projection_dim && + ctx.capacity.hidden_dim * 8u && detail::tensor_shape(linear_in, dep_dim, projection_dim) && detail::supported_mul_mat_dtype( static_cast(linear_in->type)); @@ -1733,7 +1744,7 @@ struct guard_depformer_layer_gating_in_failed { struct guard_depformer_layer_silu_gate_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; @@ -1754,7 +1765,7 @@ struct guard_depformer_layer_silu_gate_supported { runtime_ev.ctx.depformer_layer_index < runtime_ev.request.model.moshi_lm.depformer_num_layers && gate_dim > 0 && - static_cast(gate_dim) <= detail::k_max_gating_dim; + static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u; } }; @@ -1795,7 +1806,7 @@ struct guard_depformer_layer_silu_gate_failed { struct guard_depformer_layer_gating_out_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; @@ -1817,7 +1828,7 @@ struct guard_depformer_layer_gating_out_supported { return runtime_ev.ctx.depformer_layer_silu_gate_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && codebook < model.moshi_lm.dep_q && dep_dim > 0 && gate_dim > 0 && - static_cast(gate_dim) <= detail::k_max_gating_dim && + static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u && detail::tensor_shape(linear_out, gate_dim, dep_dim) && detail::supported_mul_mat_dtype( static_cast(linear_out->type)); @@ -1923,9 +1934,9 @@ struct guard_depformer_sampling_config_valid { ctx.sampling.audio_top_k > 0 && ctx.sampling.audio_top_k <= ctx.session.audio_card && static_cast(ctx.session.audio_card) <= - detail::k_max_sampling_card && + ctx.capacity.sampling_card && static_cast(ctx.sampling.audio_top_k) <= - detail::k_max_sampling_top_k; + ctx.capacity.sampling_top_k; } }; diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index e3605e33..3d274a8b 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -116,6 +116,13 @@ TEST_CASE( .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, }, + .capacity = executor::action::capacities{ + .hidden_dim = executor::detail::k_max_hidden_dim, + .temporal_context = executor::detail::k_max_temporal_context, + .depformer_context = executor::detail::k_max_depformer_context, + .sampling_card = executor::detail::k_max_sampling_card, + .sampling_top_k = executor::detail::k_max_sampling_top_k, + }, }}; emel::error::type err = emel::error::cast(executor::error::none); diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 0b4359e1..85dd90e7 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -39,6 +39,13 @@ moshi_executor::dependencies make_executor_dependencies( .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, }, + .capacity = moshi_executor::action::capacities{ + .hidden_dim = moshi_executor::detail::k_max_hidden_dim, + .temporal_context = moshi_executor::detail::k_max_temporal_context, + .depformer_context = moshi_executor::detail::k_max_depformer_context, + .sampling_card = moshi_executor::detail::k_max_sampling_card, + .sampling_top_k = moshi_executor::detail::k_max_sampling_top_k, + }, }; } @@ -784,6 +791,24 @@ TEST_CASE("speech_moshi_executor_rejects_missing_numeric_policy") { CHECK(err == emel::error::cast(moshi_executor::error::bind_failed)); } +TEST_CASE("speech_moshi_executor_rejects_missing_capacity") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::kernel::sm kernel{}; + auto dependencies = make_executor_dependencies(kernel); + dependencies.capacity.hidden_dim = 0u; + moshi_executor::sm executor{dependencies}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + + CHECK_FALSE(executor.process_event(init)); + CHECK(err == emel::error::cast(moshi_executor::error::bind_failed)); +} + TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index a00a9eda..2b851508 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -541,6 +541,20 @@ int main(int argc, char **argv) { .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, }, + .capacity = runtime::action::capacities{ + .hidden_dim = static_cast(std::max( + lm_model.model->moshi_lm.dim, + lm_model.model->moshi_lm.depformer_dim)), + .temporal_context = + static_cast(lm_model.model->moshi_lm.context), + .depformer_context = static_cast( + lm_model.model->moshi_lm.depformer_context), + .sampling_card = static_cast(std::max( + lm_model.model->moshi_lm.text_card, + lm_model.model->moshi_lm.card)), + .sampling_top_k = static_cast( + std::max(config.audio_top_k, config.text_top_k)), + }, }}; predictor::sm token_predictor{predictor::action::dependencies{ .kv_cache = emel::memory::hybrid::kv_binding{}, From 146ed4e4d3279016610e3d534ede951df72d79b4 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 20:52:08 -0500 Subject: [PATCH 24/61] refactor: inject moshi predictor capacities --- src/emel/speech/predictor/moshi/events.hpp | 10 +++-- src/emel/speech/predictor/moshi/guards.hpp | 12 +++++- .../predictor/moshi_lifecycle_tests.cpp | 38 +++++++++++++++++++ .../bench/speech/personaplex_emel_runner.cpp | 4 ++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 847aae8b..3ec2514c 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -36,10 +36,12 @@ struct initialize { : model(model_ref) {} const emel::model::data &model; - int32_t max_sequences = 1; - int32_t max_blocks = 4096; - int32_t block_tokens = emel::memory::view::DEFAULT_BLOCK_TOKENS; - int32_t sequence_id = 0; + int32_t max_sequences = 0; + int32_t max_blocks = 0; + int32_t block_tokens = 0; + int32_t sequence_id = -1; + int32_t codebook_capacity = 0; + int32_t delay_cache_row_capacity = 0; bool sampling_enabled = false; bool sampling_consume_forced_text = false; float sampling_audio_temperature = 0.0f; diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 7c90dd81..b5e25c5a 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -39,7 +39,17 @@ struct guard_bind_contract_valid { lm.dep_q > 0 && lm.dep_q < codebook_count && delayed_dep_q > 0 && delayed_dep_q <= lm.dep_q && needed_tokens >= 0 && row_count > 0 && row_count <= action::k_max_delay_rows && inference_contract && - lm.delay_count >= static_cast(codebook_count); + lm.delay_count >= static_cast(codebook_count) && + runtime_ev.request.max_sequences > 0 && + runtime_ev.request.max_blocks > 0 && + runtime_ev.request.block_tokens > 0 && + runtime_ev.request.sequence_id >= 0 && + runtime_ev.request.sequence_id < runtime_ev.request.max_sequences && + runtime_ev.request.codebook_capacity >= codebook_count && + runtime_ev.request.codebook_capacity <= action::k_max_codebooks && + runtime_ev.request.delay_cache_row_capacity >= row_count && + runtime_ev.request.delay_cache_row_capacity <= + action::k_max_delay_rows; } }; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 85dd90e7..2614ee89 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -49,6 +49,21 @@ moshi_executor::dependencies make_executor_dependencies( }; } +void configure_predictor_initialize(moshi::event::initialize &request) { + int32_t maximum_delay = 0; + for (uint32_t index = 0; index < request.model.moshi_lm.delay_count; + ++index) { + maximum_delay = + std::max(maximum_delay, request.model.moshi_lm.delays[index]); + } + request.max_sequences = 1; + request.max_blocks = 64; + request.block_tokens = 4; + request.sequence_id = 0; + request.codebook_capacity = request.model.moshi_lm.n_q + 1; + request.delay_cache_row_capacity = maximum_delay + 3; +} + struct recording_graph_executor { int32_t call_count = 0; int32_t external_embedding_count = 0; @@ -357,6 +372,7 @@ TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); init.max_sequences = 2; init.max_blocks = 16; init.block_tokens = 4; @@ -368,6 +384,22 @@ TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { CHECK(kv.allocate_sequence_count == 1); } +TEST_CASE("speech_moshi_predictor_rejects_missing_initialize_capacity") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + recording_graph_executor graph{}; + moshi::sm generator{moshi::action::dependencies{.graph = graph}}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*fixture.model}; + init.error_out = &err; + + CHECK_FALSE(generator.process_event(init)); + CHECK(err == emel::error::cast(moshi::error::bind_failed)); +} + TEST_CASE("speech_moshi_generator_personaplex_uses_model_inference_codebooks") { auto model = std::make_unique(); model->moshi_lm.n_q = 16; @@ -415,6 +447,7 @@ TEST_CASE( emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); init.max_blocks = 32; init.block_tokens = 4; init.error_out = &err; @@ -509,6 +542,7 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); init.max_blocks = 48; init.block_tokens = 4; init.error_out = &err; @@ -627,6 +661,7 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); init.max_blocks = 48; init.block_tokens = 4; init.error_out = &err; @@ -728,6 +763,7 @@ TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); init.error_out = &err; REQUIRE(generator.process_event(init)); @@ -1105,6 +1141,7 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { moshi::action::context generator_ctx{}; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); moshi::event::initialize_ctx init_ctx{}; moshi::event::initialize_run init_run{init, init_ctx}; generator_ctx.lmgen.codebook_count = fixture.model->moshi_lm.n_q + 1; @@ -1936,6 +1973,7 @@ TEST_CASE( .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = executor}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); init.error_out = &err; REQUIRE(generator.process_event(init)); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 2b851508..4a04df35 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -579,8 +579,12 @@ int main(int argc, char **argv) { mimi::sm decoder{}; predictor::event::initialize predictor_initialize{*lm_model.model}; + predictor_initialize.max_sequences = 1; predictor_initialize.max_blocks = config.max_blocks; predictor_initialize.block_tokens = config.block_tokens; + predictor_initialize.sequence_id = 0; + predictor_initialize.codebook_capacity = model_codebook_count; + predictor_initialize.delay_cache_row_capacity = tokenizer_cache_rows; predictor_initialize.sampling_enabled = true; predictor_initialize.sampling_consume_forced_text = true; predictor_initialize.sampling_audio_temperature = config.audio_temperature; From f2b580719fa878cba24c1c3bd6da94a5f1677cb3 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 21:44:47 -0500 Subject: [PATCH 25/61] refactor: inject moshi kv views --- .../predictor/moshi/executor/actions.hpp | 14 +-- .../speech/predictor/moshi/executor/any.hpp | 31 +------ .../predictor/moshi/executor/context.hpp | 59 ++----------- .../predictor/moshi/executor/guards.hpp | 11 ++- .../moshi_executor_streaming_tests.cpp | 87 +++++++++---------- .../predictor/moshi_lifecycle_tests.cpp | 82 ++++++++--------- .../bench/speech/personaplex_emel_runner.cpp | 67 +++++++------- 7 files changed, 131 insertions(+), 220 deletions(-) diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index c65f9698..8ce3e25c 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -1032,11 +1032,8 @@ struct effect_publish_forced_text_token { struct effect_bind_depformer_kv { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - runtime_ev.ctx.depformer_kv = {}; - runtime_ev.ctx.depformer_kv_bound = ctx.depformer_kv.bind( - ctx.depformer_kv.cache, runtime_ev.request.model, - runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, - runtime_ev.ctx.depformer_kv); + runtime_ev.ctx.depformer_kv = ctx.depformer_kv; + runtime_ev.ctx.depformer_kv_bound = true; } }; @@ -1825,11 +1822,8 @@ struct effect_advance_depformer_codebook { struct effect_bind_temporal_kv { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - runtime_ev.ctx.temporal_kv = {}; - runtime_ev.ctx.temporal_kv_bound = ctx.temporal_kv.bind( - ctx.temporal_kv.cache, runtime_ev.request.model, - runtime_ev.request.memory_snapshot, runtime_ev.request.sequence_id, - runtime_ev.ctx.temporal_kv); + runtime_ev.ctx.temporal_kv = ctx.temporal_kv; + runtime_ev.ctx.temporal_kv_bound = true; } }; diff --git a/src/emel/speech/predictor/moshi/executor/any.hpp b/src/emel/speech/predictor/moshi/executor/any.hpp index 7bbea2a6..01ef1777 100644 --- a/src/emel/speech/predictor/moshi/executor/any.hpp +++ b/src/emel/speech/predictor/moshi/executor/any.hpp @@ -4,36 +4,7 @@ namespace emel::speech::predictor::moshi::executor { -using temporal_kv_binding = action::temporal_kv_binding; -using depformer_kv_binding = action::depformer_kv_binding; -using kv_bindings = action::kv_bindings; +using kv_views = action::kv_views; using dependencies = action::dependencies; -inline temporal_kv_binding -bind_temporal_kv_cache(void *cache, - action::temporal_kv_bind_fn &bind) noexcept { - return action::bind_temporal_kv_cache(cache, bind); -} - -inline depformer_kv_binding -bind_depformer_kv_cache(void *cache, - action::depformer_kv_bind_fn &bind) noexcept { - return action::bind_depformer_kv_cache(cache, bind); -} - -inline kv_bindings -bind_kv_caches(const temporal_kv_binding &temporal, - const depformer_kv_binding &depformer) noexcept { - return action::bind_kv_caches(temporal, depformer); -} - -inline kv_bindings -bind_kv_caches(const temporal_kv_binding &temporal, - const depformer_kv_binding &depformer, - emel::memory::streaming::sm &temporal_positions, - emel::memory::streaming::sm &depformer_positions) noexcept { - return action::bind_kv_caches(temporal, depformer, temporal_positions, - depformer_positions); -} - } // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index 489b88c5..be28f26f 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -11,27 +11,9 @@ namespace emel::speech::predictor::moshi::executor::action { -using temporal_kv_bind_fn = bool(void *, const emel::model::data &, - const emel::memory::view::snapshot &, int32_t, - detail::temporal_kv_view &); - -using depformer_kv_bind_fn = bool(void *, const emel::model::data &, - const emel::memory::view::snapshot &, int32_t, - detail::depformer_kv_view &); - -struct temporal_kv_binding { - void *cache = nullptr; - temporal_kv_bind_fn *bind = nullptr; -}; - -struct depformer_kv_binding { - void *cache = nullptr; - depformer_kv_bind_fn *bind = nullptr; -}; - -struct kv_bindings { - temporal_kv_binding temporal = {}; - depformer_kv_binding depformer = {}; +struct kv_views { + detail::temporal_kv_view temporal = {}; + detail::depformer_kv_view depformer = {}; emel::memory::streaming::sm *temporal_positions = nullptr; emel::memory::streaming::sm *depformer_positions = nullptr; }; @@ -50,7 +32,7 @@ struct capacities { }; struct dependencies { - kv_bindings kv = {}; + kv_views kv = {}; emel::kernel::sm &kernel; policies policy = {}; capacities capacity = {}; @@ -85,8 +67,8 @@ struct context { runtime session = {}; sampling_config sampling = {}; - temporal_kv_binding temporal_kv = {}; - depformer_kv_binding depformer_kv = {}; + const detail::temporal_kv_view temporal_kv; + const detail::depformer_kv_view depformer_kv; emel::memory::streaming::sm *temporal_positions = nullptr; emel::memory::streaming::sm *depformer_positions = nullptr; emel::kernel::sm &kernel; @@ -94,33 +76,4 @@ struct context { const capacities capacity; }; -inline temporal_kv_binding -bind_temporal_kv_cache(void *cache, temporal_kv_bind_fn &bind) noexcept { - return temporal_kv_binding{.cache = cache, .bind = &bind}; -} - -inline depformer_kv_binding -bind_depformer_kv_cache(void *cache, depformer_kv_bind_fn &bind) noexcept { - return depformer_kv_binding{.cache = cache, .bind = &bind}; -} - -inline kv_bindings -bind_kv_caches(const temporal_kv_binding &temporal, - const depformer_kv_binding &depformer) noexcept { - return kv_bindings{.temporal = temporal, .depformer = depformer}; -} - -inline kv_bindings -bind_kv_caches(const temporal_kv_binding &temporal, - const depformer_kv_binding &depformer, - emel::memory::streaming::sm &temporal_positions, - emel::memory::streaming::sm &depformer_positions) noexcept { - return kv_bindings{ - .temporal = temporal, - .depformer = depformer, - .temporal_positions = &temporal_positions, - .depformer_positions = &depformer_positions, - }; -} - } // namespace emel::speech::predictor::moshi::executor::action diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index dc38f1d4..d5df7064 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -337,8 +337,10 @@ struct guard_temporal_kv_binding_present { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { (void)runtime_ev; - return ctx.temporal_kv.cache != nullptr && - ctx.temporal_kv.bind != nullptr && ctx.temporal_positions != nullptr; + return !ctx.temporal_kv.key_cache.empty() && + !ctx.temporal_kv.value_cache.empty() && + !ctx.temporal_kv.layer_cache_offsets.empty() && + ctx.temporal_positions != nullptr; } }; @@ -1130,8 +1132,9 @@ struct guard_depformer_kv_binding_present { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { (void)runtime_ev; - return ctx.depformer_kv.cache != nullptr && - ctx.depformer_kv.bind != nullptr && + return !ctx.depformer_kv.key_cache.empty() && + !ctx.depformer_kv.value_cache.empty() && + !ctx.depformer_kv.layer_cache_offsets.empty() && ctx.depformer_positions != nullptr; } }; diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index 3d274a8b..8225cd95 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -38,32 +38,6 @@ struct cache_storage { std::vector offsets; }; -bool bind_temporal_cache(void *storage_ptr, const emel::model::data &model, - const emel::memory::view::snapshot &, int32_t, - executor::detail::temporal_kv_view &view) noexcept { - auto &storage = *static_cast(storage_ptr); - view.key_cache = storage.key; - view.value_cache = storage.value; - view.layer_cache_offsets = storage.offsets; - view.layer_count = model.moshi_lm.num_layers; - view.position_capacity = model.moshi_lm.context; - view.kv_dim = model.moshi_lm.dim; - return true; -} - -bool bind_depformer_cache(void *storage_ptr, const emel::model::data &model, - const emel::memory::view::snapshot &, int32_t, - executor::detail::depformer_kv_view &view) noexcept { - auto &storage = *static_cast(storage_ptr); - view.key_cache = storage.key; - view.value_cache = storage.value; - view.layer_cache_offsets = storage.offsets; - view.layer_count = model.moshi_lm.depformer_num_layers; - view.position_capacity = model.moshi_lm.depformer_context; - view.kv_dim = model.moshi_lm.depformer_dim; - return true; -} - memory_streaming::window_view capture(memory_streaming::sm &machine) { memory_streaming::window_view view = {}; int32_t err = @@ -103,27 +77,48 @@ TEST_CASE( REQUIRE(memory_err == static_cast( emel::error::cast(memory_streaming::error::none))); - const auto temporal_binding = - executor::bind_temporal_kv_cache(&temporal_cache, bind_temporal_cache); - const auto depformer_binding = - executor::bind_depformer_kv_cache(&depformer_cache, bind_depformer_cache); emel::kernel::sm kernel{}; - executor::sm machine{executor::dependencies{ - .kv = executor::bind_kv_caches(temporal_binding, depformer_binding, - temporal_positions, depformer_positions), - .kernel = kernel, - .policy = executor::action::policies{ - .rms_norm_epsilon = 1.0e-8f, - .zero_seed_state = 123459876u, - }, - .capacity = executor::action::capacities{ - .hidden_dim = executor::detail::k_max_hidden_dim, - .temporal_context = executor::detail::k_max_temporal_context, - .depformer_context = executor::detail::k_max_depformer_context, - .sampling_card = executor::detail::k_max_sampling_card, - .sampling_top_k = executor::detail::k_max_sampling_top_k, - }, - }}; + executor::sm machine{ + executor::dependencies{ + .kv = + executor::kv_views{ + .temporal = + executor::detail::temporal_kv_view{ + .key_cache = temporal_cache.key, + .value_cache = temporal_cache.value, + .layer_cache_offsets = temporal_cache.offsets, + .layer_count = lm.num_layers, + .position_capacity = lm.context, + .kv_dim = lm.dim, + }, + .depformer = + executor::detail::depformer_kv_view{ + .key_cache = depformer_cache.key, + .value_cache = depformer_cache.value, + .layer_cache_offsets = depformer_cache.offsets, + .layer_count = lm.depformer_num_layers, + .position_capacity = lm.depformer_context, + .kv_dim = lm.depformer_dim, + }, + .temporal_positions = &temporal_positions, + .depformer_positions = &depformer_positions, + }, + .kernel = kernel, + .policy = + executor::action::policies{ + .rms_norm_epsilon = 1.0e-8f, + .zero_seed_state = 123459876u, + }, + .capacity = + executor::action::capacities{ + .hidden_dim = executor::detail::k_max_hidden_dim, + .temporal_context = executor::detail::k_max_temporal_context, + .depformer_context = + executor::detail::k_max_depformer_context, + .sampling_card = executor::detail::k_max_sampling_card, + .sampling_top_k = executor::detail::k_max_sampling_top_k, + }, + }}; emel::error::type err = emel::error::cast(executor::error::none); executor::event::initialize initialize{*fixture.model}; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 2614ee89..e7e0d131 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -29,9 +29,9 @@ using emel::speech::predictor::moshi::test::repo_root; inline constexpr emel::error::type k_no_error = emel::error::cast(moshi::error::none); -moshi_executor::dependencies make_executor_dependencies( - emel::kernel::sm &kernel, - const moshi_executor::kv_bindings &kv = {}) noexcept { +moshi_executor::dependencies +make_executor_dependencies(emel::kernel::sm &kernel, + const moshi_executor::kv_views &kv = {}) noexcept { return moshi_executor::dependencies{ .kv = kv, .kernel = kernel, @@ -318,6 +318,27 @@ bool depformer_kv_probe_bind(void *cache_ptr, const emel::model::data &model, return true; } +moshi_executor::kv_views +prepare_kv_views(const emel::model::data &model, temporal_kv_probe *temporal, + depformer_kv_probe *depformer, + memory_streaming::sm *temporal_positions = nullptr, + memory_streaming::sm *depformer_positions = nullptr) { + moshi_executor::kv_views views{ + .temporal_positions = temporal_positions, + .depformer_positions = depformer_positions, + }; + emel::memory::view::snapshot snapshot{}; + if (temporal != nullptr) { + REQUIRE( + temporal_kv_probe_bind(temporal, model, snapshot, 0, views.temporal)); + } + if (depformer != nullptr) { + REQUIRE(depformer_kv_probe_bind(depformer, model, snapshot, 0, + views.depformer)); + } + return views; +} + void initialize_streaming_position(memory_streaming::sm &position) { int32_t err = static_cast(emel::error::cast(memory_streaming::error::none)); @@ -1630,13 +1651,10 @@ TEST_CASE( memory_streaming::sm temporal_positions{memory_streaming::dependencies{ .capacity = fixture.model->moshi_lm.context}}; initialize_streaming_position(temporal_positions); - moshi_executor::action::kv_bindings bindings{ - .temporal = moshi_executor::bind_temporal_kv_cache( - &probe, temporal_kv_probe_bind), - .temporal_positions = &temporal_positions, - }; + const auto views = + prepare_kv_views(*fixture.model, &probe, nullptr, &temporal_positions); emel::kernel::sm kernel{}; - moshi_executor::sm executor{make_executor_dependencies(kernel, bindings)}; + moshi_executor::sm executor{make_executor_dependencies(kernel, views)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1669,8 +1687,6 @@ TEST_CASE( CHECK(err == emel::error::cast(moshi_executor::error::graph_execution_unsupported)); CHECK(probe.call_count == 1); - CHECK(probe.sequence_id == 7); - CHECK(probe.sequence_length == 3); const size_t write_offset = 0; const size_t write_end = write_offset + static_cast(fixture.model->moshi_lm.dim); @@ -1713,10 +1729,6 @@ TEST_CASE("speech_moshi_executor_accepts_personaplex_voice_embedding_step") { temporal_kv_probe temporal_probe{}; depformer_kv_probe depformer_probe{}; - const auto temporal_kv = moshi_executor::bind_temporal_kv_cache( - &temporal_probe, temporal_kv_probe_bind); - const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( - &depformer_probe, depformer_kv_probe_bind); memory_streaming::sm temporal_positions{memory_streaming::dependencies{ .capacity = fixture.model->moshi_lm.context}}; memory_streaming::sm depformer_positions{memory_streaming::dependencies{ @@ -1724,9 +1736,10 @@ TEST_CASE("speech_moshi_executor_accepts_personaplex_voice_embedding_step") { initialize_streaming_position(temporal_positions); initialize_streaming_position(depformer_positions); emel::kernel::sm kernel{}; - const auto bindings = moshi_executor::bind_kv_caches( - temporal_kv, depformer_kv, temporal_positions, depformer_positions); - moshi_executor::sm executor{make_executor_dependencies(kernel, bindings)}; + const auto views = + prepare_kv_views(*fixture.model, &temporal_probe, &depformer_probe, + &temporal_positions, &depformer_positions); + moshi_executor::sm executor{make_executor_dependencies(kernel, views)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1781,10 +1794,6 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { temporal_kv_probe temporal_probe{}; depformer_kv_probe depformer_probe{}; - const auto temporal_kv = moshi_executor::bind_temporal_kv_cache( - &temporal_probe, temporal_kv_probe_bind); - const auto depformer_kv = moshi_executor::bind_depformer_kv_cache( - &depformer_probe, depformer_kv_probe_bind); memory_streaming::sm temporal_positions{memory_streaming::dependencies{ .capacity = fixture.model->moshi_lm.context}}; memory_streaming::sm depformer_positions{memory_streaming::dependencies{ @@ -1792,9 +1801,10 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { initialize_streaming_position(temporal_positions); initialize_streaming_position(depformer_positions); emel::kernel::sm kernel{}; - const auto bindings = moshi_executor::bind_kv_caches( - temporal_kv, depformer_kv, temporal_positions, depformer_positions); - moshi_executor::sm executor{make_executor_dependencies(kernel, bindings)}; + const auto views = + prepare_kv_views(*fixture.model, &temporal_probe, &depformer_probe, + &temporal_positions, &depformer_positions); + moshi_executor::sm executor{make_executor_dependencies(kernel, views)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1887,22 +1897,16 @@ TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { initialize_streaming_position(second_depformer_positions); emel::kernel::sm first_kernel{}; emel::kernel::sm second_kernel{}; - const auto first_bindings = moshi_executor::bind_kv_caches( - moshi_executor::bind_temporal_kv_cache(&first_temporal, - temporal_kv_probe_bind), - moshi_executor::bind_depformer_kv_cache(&first_depformer, - depformer_kv_probe_bind), - first_temporal_positions, first_depformer_positions); - const auto second_bindings = moshi_executor::bind_kv_caches( - moshi_executor::bind_temporal_kv_cache(&second_temporal, - temporal_kv_probe_bind), - moshi_executor::bind_depformer_kv_cache(&second_depformer, - depformer_kv_probe_bind), - second_temporal_positions, second_depformer_positions); + const auto first_views = + prepare_kv_views(*first_fixture.model, &first_temporal, &first_depformer, + &first_temporal_positions, &first_depformer_positions); + const auto second_views = prepare_kv_views( + *second_fixture.model, &second_temporal, &second_depformer, + &second_temporal_positions, &second_depformer_positions); moshi_executor::sm first{ - make_executor_dependencies(first_kernel, first_bindings)}; + make_executor_dependencies(first_kernel, first_views)}; moshi_executor::sm second{ - make_executor_dependencies(second_kernel, second_bindings)}; + make_executor_dependencies(second_kernel, second_views)}; emel::error::type first_err = emel::error::cast(moshi_executor::error::none); emel::error::type second_err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize first_init{*first_fixture.model}; diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 4a04df35..d41a35a1 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -72,25 +72,11 @@ struct streaming_cache { std::vector layer_offsets = {}; }; -struct cache_binding { +struct cache_views { runtime::detail::temporal_kv_view temporal = {}; runtime::detail::depformer_kv_view secondary = {}; }; -bool bind_temporal_cache(void *binding_ptr, const emel::model::data &, - const emel::memory::view::snapshot &, int32_t, - runtime::detail::temporal_kv_view &view) noexcept { - view = static_cast(binding_ptr)->temporal; - return true; -} - -bool bind_secondary_cache(void *binding_ptr, const emel::model::data &, - const emel::memory::view::snapshot &, int32_t, - runtime::detail::depformer_kv_view &view) noexcept { - view = static_cast(binding_ptr)->secondary; - return true; -} - struct personaplex_dependencies { using generator_mode = generator::action::mode::duplex; using voice_condition_event = predictor::event::prefill_voice; @@ -508,7 +494,7 @@ int main(int argc, char **argv) { emel::memory::streaming::sm secondary_positions{ emel::memory::streaming::dependencies{ .capacity = lm_model.model->moshi_lm.depformer_context}}; - cache_binding cache_views{ + cache_views cache_view_set{ .temporal = { .key_cache = std::span{temporal_cache.key_cache}, @@ -532,29 +518,34 @@ int main(int argc, char **argv) { }; emel::kernel::sm prediction_kernel{}; runtime::sm prediction_runtime{runtime::dependencies{ - .kv = runtime::bind_kv_caches( - runtime::bind_temporal_kv_cache(&cache_views, bind_temporal_cache), - runtime::bind_depformer_kv_cache(&cache_views, bind_secondary_cache), - temporal_positions, secondary_positions), + .kv = + runtime::kv_views{ + .temporal = cache_view_set.temporal, + .depformer = cache_view_set.secondary, + .temporal_positions = &temporal_positions, + .depformer_positions = &secondary_positions, + }, .kernel = prediction_kernel, - .policy = runtime::action::policies{ - .rms_norm_epsilon = 1.0e-8f, - .zero_seed_state = 123459876u, - }, - .capacity = runtime::action::capacities{ - .hidden_dim = static_cast(std::max( - lm_model.model->moshi_lm.dim, - lm_model.model->moshi_lm.depformer_dim)), - .temporal_context = - static_cast(lm_model.model->moshi_lm.context), - .depformer_context = static_cast( - lm_model.model->moshi_lm.depformer_context), - .sampling_card = static_cast(std::max( - lm_model.model->moshi_lm.text_card, - lm_model.model->moshi_lm.card)), - .sampling_top_k = static_cast( - std::max(config.audio_top_k, config.text_top_k)), - }, + .policy = + runtime::action::policies{ + .rms_norm_epsilon = 1.0e-8f, + .zero_seed_state = 123459876u, + }, + .capacity = + runtime::action::capacities{ + .hidden_dim = static_cast( + std::max(lm_model.model->moshi_lm.dim, + lm_model.model->moshi_lm.depformer_dim)), + .temporal_context = + static_cast(lm_model.model->moshi_lm.context), + .depformer_context = static_cast( + lm_model.model->moshi_lm.depformer_context), + .sampling_card = static_cast( + std::max(lm_model.model->moshi_lm.text_card, + lm_model.model->moshi_lm.card)), + .sampling_top_k = static_cast( + std::max(config.audio_top_k, config.text_top_k)), + }, }}; predictor::sm token_predictor{predictor::action::dependencies{ .kv_cache = emel::memory::hybrid::kv_binding{}, From 418eb8dfdf13741348f438b04d44653fead322cc Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 22:08:39 -0500 Subject: [PATCH 26/61] refactor: dispatch moshi sampling through sampler actor --- src/emel/logits/sampler/actions.hpp | 79 ++++++++++++++++ src/emel/logits/sampler/events.hpp | 40 ++++++++ src/emel/logits/sampler/guards.hpp | 22 +++++ src/emel/logits/sampler/sm.hpp | 58 ++++++++++++ .../predictor/moshi/executor/actions.hpp | 88 ++++-------------- .../predictor/moshi/executor/context.hpp | 5 +- .../predictor/moshi/executor/detail.hpp | 62 ------------- .../predictor/moshi/executor/events.hpp | 4 +- .../predictor/moshi/executor/guards.hpp | 18 +++- .../speech/predictor/moshi/executor/sm.hpp | 32 +------ tests/logits/sampler/pipeline_tests.cpp | 29 ++++++ .../predictor/moshi_lifecycle_tests.cpp | 92 ++++++++++++++----- .../bench/speech/personaplex_emel_runner.cpp | 2 + 13 files changed, 340 insertions(+), 191 deletions(-) diff --git a/src/emel/logits/sampler/actions.hpp b/src/emel/logits/sampler/actions.hpp index 401fb936..a4c5430c 100644 --- a/src/emel/logits/sampler/actions.hpp +++ b/src/emel/logits/sampler/actions.hpp @@ -1,5 +1,11 @@ #pragma once +#include +#include +#include + +#include "emel/kernel/detail.hpp" + #include "emel/logits/sampler/context.hpp" #include "emel/logits/sampler/events.hpp" @@ -85,6 +91,74 @@ struct advance_sampler_index { } }; +struct scale_temperature_logits { + void operator()(const event::sample_temperature_top_k_runtime &ev, + context &) const noexcept { + const float inverse_temperature = 1.0f / ev.request.temperature; + for (int32_t index = 0; index < ev.request.card; ++index) { + ev.request.logits[static_cast(index)] *= inverse_temperature; + } + } +}; + +struct compute_temperature_probabilities { + void operator()(const event::sample_temperature_top_k_runtime &ev, + context &) const noexcept { + emel::kernel::detail::soft_max_row_ggml(ev.request.card, + ev.request.logits.data()); + } +}; + +struct compute_temperature_top_k { + void operator()(const event::sample_temperature_top_k_runtime &ev, + context &) const noexcept { + for (int32_t index = 0; index < ev.request.card; ++index) { + ev.request.sorted_indices[static_cast(index)] = index; + } + std::sort(ev.request.sorted_indices.begin(), + ev.request.sorted_indices.begin() + ev.request.card, + [&ev](const int32_t lhs, const int32_t rhs) { + return ev.request.logits[static_cast(lhs)] > + ev.request.logits[static_cast(rhs)]; + }); + for (int32_t slot = 0; slot < ev.request.top_k; ++slot) { + const int32_t index = + ev.request.sorted_indices[static_cast(slot)]; + ev.request.top_probabilities[static_cast(slot)] = + ev.request.logits[static_cast(index)]; + ev.request.top_indices[static_cast(slot)] = index; + } + } +}; + +struct select_temperature_top_k { + void operator()(const event::sample_temperature_top_k_runtime &ev, + context &) const noexcept { + constexpr uint32_t multiplier = 16807u; + constexpr uint32_t modulus = 2147483647u; + constexpr float random_max = 2147483647.0f; + ev.request.selected_token_out = -1; + ev.request.selected_score_out = -std::numeric_limits::infinity(); + for (int32_t slot = 0; slot < ev.request.top_k; ++slot) { + ev.request.random_state = static_cast( + (static_cast(ev.request.random_state) * multiplier) % + modulus); + const float uniform = + static_cast(ev.request.random_state) / random_max; + const float divisor = -std::log(uniform); + const float score = + ev.request.top_probabilities[static_cast(slot)] / divisor; + const int32_t replace = + static_cast(score > ev.request.selected_score_out); + ev.request.selected_token_out = + replace * ev.request.top_indices[static_cast(slot)] + + (1 - replace) * ev.request.selected_token_out; + ev.request.selected_score_out = + std::max(ev.request.selected_score_out, score); + } + } +}; + struct publish_done { template void operator()(const runtime_event_type & ev, context &) const noexcept { @@ -121,6 +195,11 @@ inline constexpr prepare_candidates prepare_candidates{}; inline constexpr apply_sampler apply_sampler{}; inline constexpr mark_sampler_error mark_sampler_error{}; inline constexpr advance_sampler_index advance_sampler_index{}; +inline constexpr scale_temperature_logits scale_temperature_logits{}; +inline constexpr compute_temperature_probabilities + compute_temperature_probabilities{}; +inline constexpr compute_temperature_top_k compute_temperature_top_k{}; +inline constexpr select_temperature_top_k select_temperature_top_k{}; inline constexpr publish_done publish_done{}; inline constexpr publish_error publish_error{}; inline constexpr on_unexpected on_unexpected{}; diff --git a/src/emel/logits/sampler/events.hpp b/src/emel/logits/sampler/events.hpp index 1341337e..83ab6201 100644 --- a/src/emel/logits/sampler/events.hpp +++ b/src/emel/logits/sampler/events.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "emel/callback.hpp" #include "emel/error/error.hpp" @@ -68,6 +69,36 @@ struct sample_preselected { error_out(error_out_ref) {} }; +struct sample_temperature_top_k { + sample_temperature_top_k(std::span logits_ref, const int32_t card_ref, + const float temperature_ref, const int32_t top_k_ref, + std::span sorted_indices_ref, + std::span top_probabilities_ref, + std::span top_indices_ref, + uint32_t &random_state_ref, + int32_t &selected_token_out_ref, + float &selected_score_out_ref, + emel::error::type &error_out_ref) noexcept + : logits(logits_ref), card(card_ref), temperature(temperature_ref), + top_k(top_k_ref), sorted_indices(sorted_indices_ref), + top_probabilities(top_probabilities_ref), top_indices(top_indices_ref), + random_state(random_state_ref), + selected_token_out(selected_token_out_ref), + selected_score_out(selected_score_out_ref), error_out(error_out_ref) {} + + std::span logits; + int32_t card; + float temperature; + int32_t top_k; + std::span sorted_indices; + std::span top_probabilities; + std::span top_indices; + uint32_t &random_state; + int32_t &selected_token_out; + float &selected_score_out; + emel::error::type &error_out; +}; + struct configure_ctx { emel::error::type err = emel::error::cast(error::none); }; @@ -83,6 +114,10 @@ struct sample_preselected_ctx { emel::error::type err = emel::error::cast(error::none); }; +struct sample_temperature_top_k_ctx { + emel::error::type err = emel::error::cast(error::none); +}; + struct configure_runtime { const configure & request; configure_ctx & ctx; @@ -98,6 +133,11 @@ struct sample_preselected_runtime { sample_preselected_ctx & ctx; }; +struct sample_temperature_top_k_runtime { + const sample_temperature_top_k &request; + sample_temperature_top_k_ctx &ctx; +}; + } // namespace emel::logits::sampler::event namespace emel::logits::sampler::events { diff --git a/src/emel/logits/sampler/guards.hpp b/src/emel/logits/sampler/guards.hpp index 590f0bf0..0fb20623 100644 --- a/src/emel/logits/sampler/guards.hpp +++ b/src/emel/logits/sampler/guards.hpp @@ -129,4 +129,26 @@ struct selected_token_missing_or_invalid { } }; +struct temperature_top_k_request_valid { + bool + operator()(const event::sample_temperature_top_k_runtime &ev) const noexcept { + const auto &request = ev.request; + return request.card > 0 && request.temperature > 0.0f && + request.top_k > 0 && request.top_k <= request.card && + request.logits.size() >= static_cast(request.card) && + request.sorted_indices.size() >= static_cast(request.card) && + request.top_probabilities.size() >= + static_cast(request.top_k) && + request.top_indices.size() >= static_cast(request.top_k) && + request.random_state != 0u; + } +}; + +struct temperature_top_k_request_invalid { + bool + operator()(const event::sample_temperature_top_k_runtime &ev) const noexcept { + return !temperature_top_k_request_valid{}(ev); + } +}; + } // namespace emel::logits::sampler::guard diff --git a/src/emel/logits/sampler/sm.hpp b/src/emel/logits/sampler/sm.hpp index a2db721e..4706c877 100644 --- a/src/emel/logits/sampler/sm.hpp +++ b/src/emel/logits/sampler/sm.hpp @@ -17,6 +17,11 @@ struct sample_decision {}; struct sample_call {}; struct sample_call_decision {}; struct sample_complete_decision {}; +struct state_temperature_top_k_request_decision {}; +struct state_temperature_top_k_scale {}; +struct state_temperature_top_k_probabilities {}; +struct state_temperature_top_k_rank {}; +struct state_temperature_top_k_select {}; struct done {}; struct errored {}; @@ -88,6 +93,36 @@ struct model { + sml::completion [ guard::selected_token_missing_or_invalid{} ] / action::mark_invalid_request + //------------------------------------------------------------------------------// + // Native temperature/top-k sampling is a typed actor path. Each numeric + // phase is explicit and uses caller-provided, allocation-free workspace. + , sml::state <= sml::state + + sml::event + , sml::state <= + sml::state + + sml::completion + [ guard::temperature_top_k_request_valid{} ] + / action::scale_temperature_logits + , sml::state <= + sml::state + + sml::completion + [ guard::temperature_top_k_request_invalid{} ] + / action::mark_invalid_request + , sml::state <= + sml::state + + sml::completion + / action::compute_temperature_probabilities + , sml::state <= + sml::state + + sml::completion + / action::compute_temperature_top_k + , sml::state <= + sml::state + + sml::completion + / action::select_temperature_top_k + , sml::state <= sml::state + + sml::completion + //------------------------------------------------------------------------------// , sml::state <= sml::state + sml::completion / action::publish_done @@ -101,6 +136,12 @@ struct model { / action::publish_done , sml::state <= sml::state + sml::completion / action::publish_error + , sml::state <= sml::state + + sml::completion + / action::publish_done + , sml::state <= sml::state + + sml::completion + / action::publish_error //------------------------------------------------------------------------------// , sml::state <= sml::state + sml::unexpected_event @@ -121,6 +162,16 @@ struct model { / action::on_unexpected , sml::state <= sml::state + sml::unexpected_event / action::on_unexpected + , sml::state <= sml::state + + sml::unexpected_event / action::on_unexpected + , sml::state <= sml::state + + sml::unexpected_event / action::on_unexpected + , sml::state <= sml::state + + sml::unexpected_event / action::on_unexpected + , sml::state <= sml::state + + sml::unexpected_event / action::on_unexpected + , sml::state <= sml::state + + sml::unexpected_event / action::on_unexpected , sml::state <= sml::state + sml::unexpected_event / action::on_unexpected , sml::state <= sml::state + sml::unexpected_event @@ -159,6 +210,13 @@ struct sm : public emel::sm { return accepted && ctx.err == emel::error::cast(error::none); } + bool process_event(const event::sample_temperature_top_k &ev) { + event::sample_temperature_top_k_ctx ctx{}; + event::sample_temperature_top_k_runtime runtime{ev, ctx}; + const bool accepted = base_type::process_event(runtime); + return accepted && ctx.err == emel::error::cast(error::none); + } + private: }; diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 8ce3e25c..65ffa2e7 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -152,7 +152,6 @@ struct effect_begin_input_embedding { runtime_ev.ctx.temporal_out_norm_rms_ok = false; runtime_ev.ctx.temporal_out_norm_ok = false; runtime_ev.ctx.text_logits_ok = false; - runtime_ev.ctx.text_sampling_ok = false; runtime_ev.ctx.depformer_kv_bound = false; runtime_ev.ctx.depformer_position_accepted = false; runtime_ev.ctx.depformer_position_error = static_cast( @@ -174,7 +173,6 @@ struct effect_begin_input_embedding { runtime_ev.ctx.depformer_layer_gating_out_ok = false; runtime_ev.ctx.depformer_layer_ff_residual_ok = false; runtime_ev.ctx.depformer_logits_ok = false; - runtime_ev.ctx.depformer_sampling_ok = false; runtime_ev.ctx.best_index = -1; runtime_ev.ctx.best_score = 0.0f; runtime_ev.ctx.input_audio_codebook_index = 0; @@ -976,42 +974,19 @@ struct effect_compute_text_token_logits { } }; -struct effect_scale_text_sampling_logits { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - detail::scale_sampling_logits(runtime_ev.ctx.logits, ctx.session.text_card, - ctx.sampling.text_temperature); - } -}; - -struct effect_compute_text_sampling_probabilities { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - detail::compute_sampling_probabilities(runtime_ev.ctx.logits, - ctx.session.text_card); - } -}; - -struct effect_compute_text_sampling_top_k { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - detail::compute_sampling_top_k( - runtime_ev.ctx.logits, runtime_ev.ctx.sampling_indices, - runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, - ctx.session.text_card, ctx.sampling.text_top_k); - } -}; - struct effect_select_text_sampling_token { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - detail::compute_sampling_exponential_argmax( - runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, - ctx.session.text_card, ctx.sampling.text_top_k, - ctx.sampling.random_state, runtime_ev.ctx.best_index, - runtime_ev.ctx.best_score); - runtime_ev.ctx.text_sampling_ok = true; - runtime_ev.ctx.text_logits_ok = true; + runtime_ev.ctx.sampler_error = + emel::error::cast(emel::logits::sampler::error::none); + emel::logits::sampler::event::sample_temperature_top_k sample_ev{ + runtime_ev.ctx.logits, ctx.session.text_card, + ctx.sampling.text_temperature, ctx.sampling.text_top_k, + runtime_ev.ctx.sampling_indices, runtime_ev.ctx.top_scores, + runtime_ev.ctx.top_indices, ctx.sampling.random_state, + runtime_ev.ctx.best_index, runtime_ev.ctx.best_score, + runtime_ev.ctx.sampler_error}; + runtime_ev.ctx.sampler_accepted = ctx.sampler->process_event(sample_ev); } }; @@ -1746,42 +1721,19 @@ struct effect_compute_depformer_token_logits { } }; -struct effect_scale_depformer_sampling_logits { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - detail::scale_sampling_logits(runtime_ev.ctx.logits, ctx.session.audio_card, - ctx.sampling.audio_temperature); - } -}; - -struct effect_compute_depformer_sampling_probabilities { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - detail::compute_sampling_probabilities(runtime_ev.ctx.logits, - ctx.session.audio_card); - } -}; - -struct effect_compute_depformer_sampling_top_k { - void operator()(const event::step_run &runtime_ev, - context &ctx) const noexcept { - detail::compute_sampling_top_k( - runtime_ev.ctx.logits, runtime_ev.ctx.sampling_indices, - runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, - ctx.session.audio_card, ctx.sampling.audio_top_k); - } -}; - struct effect_select_depformer_sampling_token { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - detail::compute_sampling_exponential_argmax( - runtime_ev.ctx.top_scores, runtime_ev.ctx.top_indices, - ctx.session.audio_card, ctx.sampling.audio_top_k, - ctx.sampling.random_state, runtime_ev.ctx.best_index, - runtime_ev.ctx.best_score); - runtime_ev.ctx.depformer_sampling_ok = true; - runtime_ev.ctx.depformer_logits_ok = true; + runtime_ev.ctx.sampler_error = + emel::error::cast(emel::logits::sampler::error::none); + emel::logits::sampler::event::sample_temperature_top_k sample_ev{ + runtime_ev.ctx.logits, ctx.session.audio_card, + ctx.sampling.audio_temperature, ctx.sampling.audio_top_k, + runtime_ev.ctx.sampling_indices, runtime_ev.ctx.top_scores, + runtime_ev.ctx.top_indices, ctx.sampling.random_state, + runtime_ev.ctx.best_index, runtime_ev.ctx.best_score, + runtime_ev.ctx.sampler_error}; + runtime_ev.ctx.sampler_accepted = ctx.sampler->process_event(sample_ev); } }; diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index be28f26f..cd779207 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -3,6 +3,7 @@ #include #include "emel/kernel/sm.hpp" +#include "emel/logits/sampler/sm.hpp" #include "emel/memory/streaming/sm.hpp" #include "emel/memory/view.hpp" #include "emel/model/data.hpp" @@ -34,6 +35,7 @@ struct capacities { struct dependencies { kv_views kv = {}; emel::kernel::sm &kernel; + emel::logits::sampler::sm *sampler = nullptr; policies policy = {}; capacities capacity = {}; }; @@ -63,7 +65,7 @@ struct context { : temporal_kv(deps.kv.temporal), depformer_kv(deps.kv.depformer), temporal_positions(deps.kv.temporal_positions), depformer_positions(deps.kv.depformer_positions), kernel(deps.kernel), - policy(deps.policy), capacity(deps.capacity) {} + sampler(deps.sampler), policy(deps.policy), capacity(deps.capacity) {} runtime session = {}; sampling_config sampling = {}; @@ -72,6 +74,7 @@ struct context { emel::memory::streaming::sm *temporal_positions = nullptr; emel::memory::streaming::sm *depformer_positions = nullptr; emel::kernel::sm &kernel; + emel::logits::sampler::sm *sampler = nullptr; const policies policy; const capacities capacity; }; diff --git a/src/emel/speech/predictor/moshi/executor/detail.hpp b/src/emel/speech/predictor/moshi/executor/detail.hpp index 4f9010b5..ec3ae9bd 100644 --- a/src/emel/speech/predictor/moshi/executor/detail.hpp +++ b/src/emel/speech/predictor/moshi/executor/detail.hpp @@ -1,11 +1,8 @@ #pragma once -#include -#include #include #include #include -#include #include #include @@ -282,63 +279,4 @@ inline bool token_in_embedding_range(const int32_t token, return token >= k_token_zero && token <= card; } -inline void scale_sampling_logits(std::span logits, const int32_t card, - const float temperature) noexcept { - const float inverse_temperature = 1.0f / temperature; - for (int32_t index = 0; index < card; ++index) { - logits[static_cast(index)] *= inverse_temperature; - } -} - -inline void compute_sampling_probabilities(std::span logits, - const int32_t card) noexcept { - emel::kernel::detail::soft_max_row_ggml(card, logits.data()); -} - -inline void compute_sampling_top_k(std::span probabilities, - std::span sorted_indices, - std::span top_probabilities, - std::span top_indices, - const int32_t card, - const int32_t requested_top_k) noexcept { - for (int32_t index = 0; index < card; ++index) { - sorted_indices[static_cast(index)] = index; - } - std::sort(sorted_indices.begin(), sorted_indices.begin() + card, - [probabilities](const int32_t lhs, const int32_t rhs) { - return probabilities[static_cast(lhs)] > - probabilities[static_cast(rhs)]; - }); - for (int32_t slot = 0; slot < requested_top_k; ++slot) { - const int32_t index = sorted_indices[static_cast(slot)]; - top_probabilities[static_cast(slot)] = - probabilities[static_cast(index)]; - top_indices[static_cast(slot)] = index; - } -} - -inline void compute_sampling_exponential_argmax( - std::span top_probabilities, - std::span top_indices, const int32_t card, - const int32_t requested_top_k, uint32_t &random_state, int32_t &best_index, - float &best_score) noexcept { - constexpr uint32_t multiplier = 16807u; - constexpr uint32_t modulus = 2147483647u; - constexpr float random_max = 2147483647.0f; - (void)card; - best_index = -1; - best_score = -std::numeric_limits::infinity(); - for (int32_t slot = 0; slot < requested_top_k; ++slot) { - random_state = static_cast( - (static_cast(random_state) * multiplier) % modulus); - const float uniform = static_cast(random_state) / random_max; - const float divisor = -std::log(uniform); - const float score = top_probabilities[static_cast(slot)] / divisor; - if (score > best_score) { - best_score = score; - best_index = top_indices[static_cast(slot)]; - } - } -} - } // namespace emel::speech::predictor::moshi::executor::detail diff --git a/src/emel/speech/predictor/moshi/executor/events.hpp b/src/emel/speech/predictor/moshi/executor/events.hpp index 7915280a..f92c2925 100644 --- a/src/emel/speech/predictor/moshi/executor/events.hpp +++ b/src/emel/speech/predictor/moshi/executor/events.hpp @@ -68,7 +68,6 @@ struct step_ctx { bool temporal_out_norm_rms_ok = false; bool temporal_out_norm_ok = false; bool text_logits_ok = false; - bool text_sampling_ok = false; bool depformer_kv_bound = false; bool depformer_position_accepted = false; bool depformer_input_ok = false; @@ -89,7 +88,7 @@ struct step_ctx { bool depformer_layer_gating_out_ok = false; bool depformer_layer_ff_residual_ok = false; bool depformer_logits_ok = false; - bool depformer_sampling_ok = false; + bool sampler_accepted = false; int32_t row_index = 0; int32_t embedding_dim = 0; int32_t best_index = -1; @@ -101,6 +100,7 @@ struct step_ctx { int32_t depformer_weight_index = -1; int32_t depformer_layer_index = 0; int32_t depformer_position_error = 0; + emel::error::type sampler_error = {}; float best_score = 0.0f; detail::temporal_kv_view temporal_kv = {}; detail::depformer_kv_view depformer_kv = {}; diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index d5df7064..8682f7a3 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -20,7 +20,9 @@ struct guard_bind_contract_valid { model.moshi_lm.n_q > 0 && model.moshi_lm.dep_q > 0 && model.moshi_lm.dep_q <= model.moshi_lm.n_q && model.moshi_lm.text_card > 0 && model.moshi_lm.card > 0 && - model.moshi_lm.dim > 0 && ctx.policy.rms_norm_epsilon > 0.0f && + model.moshi_lm.dim > 0 && + (!runtime_ev.request.sampling_enabled || ctx.sampler != nullptr) && + ctx.policy.rms_norm_epsilon > 0.0f && ctx.policy.zero_seed_state != 0u && ctx.capacity.hidden_dim > 0u && ctx.capacity.hidden_dim <= detail::k_max_hidden_dim && ctx.capacity.temporal_context > 0u && @@ -989,7 +991,8 @@ struct guard_forced_text_token_absent { struct guard_text_sampling_config_valid { bool operator()(const event::step_run &, const action::context &ctx) const noexcept { - return ctx.sampling.enabled && ctx.sampling.text_temperature > 0.0f && + return ctx.sampling.enabled && ctx.sampler != nullptr && + ctx.sampling.text_temperature > 0.0f && ctx.sampling.text_top_k > 0 && ctx.sampling.text_top_k <= ctx.session.text_card && static_cast(ctx.session.text_card) <= @@ -1100,7 +1103,9 @@ struct guard_text_logits_failed { struct guard_text_sampling_succeeded { bool operator()(const event::step_run &runtime_ev, const action::context &) const noexcept { - return runtime_ev.ctx.text_sampling_ok; + return runtime_ev.ctx.sampler_accepted && + runtime_ev.ctx.sampler_error == + emel::error::cast(emel::logits::sampler::error::none); } }; @@ -1933,7 +1938,8 @@ struct guard_depformer_logits_failed { struct guard_depformer_sampling_config_valid { bool operator()(const event::step_run &, const action::context &ctx) const noexcept { - return ctx.sampling.enabled && ctx.sampling.audio_temperature > 0.0f && + return ctx.sampling.enabled && ctx.sampler != nullptr && + ctx.sampling.audio_temperature > 0.0f && ctx.sampling.audio_top_k > 0 && ctx.sampling.audio_top_k <= ctx.session.audio_card && static_cast(ctx.session.audio_card) <= @@ -1954,7 +1960,9 @@ struct guard_depformer_sampling_config_invalid { struct guard_depformer_sampling_succeeded { bool operator()(const event::step_run &runtime_ev, const action::context &) const noexcept { - return runtime_ev.ctx.depformer_sampling_ok; + return runtime_ev.ctx.sampler_accepted && + runtime_ev.ctx.sampler_error == + emel::error::cast(emel::logits::sampler::error::none); } }; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index d323ba2f..eb82aa89 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -94,9 +94,6 @@ struct state_text_logits_bind_result_decision {}; struct state_text_logits_run {}; struct state_text_logits_sample_projection {}; struct state_text_logits_sample_projection_result_decision {}; -struct state_text_logits_sample_scale {}; -struct state_text_logits_sample_softmax {}; -struct state_text_logits_sample_top_k {}; struct state_text_logits_sample_select {}; struct state_text_logits_result_decision {}; struct state_bind_depformer_kv {}; @@ -157,9 +154,6 @@ struct state_depformer_logits_bind_result_decision {}; struct state_depformer_logits_run {}; struct state_depformer_logits_sample_projection {}; struct state_depformer_logits_sample_projection_result_decision {}; -struct state_depformer_logits_sample_scale {}; -struct state_depformer_logits_sample_softmax {}; -struct state_depformer_logits_sample_top_k {}; struct state_depformer_logits_sample_select {}; struct state_depformer_token_publish {}; struct state_depformer_logits_result_decision {}; @@ -594,21 +588,12 @@ struct model { / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_matmul_succeeded{} ] - / action::effect_scale_text_sampling_logits{} + / action::effect_select_text_sampling_token{} , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_matmul_failed{} ] / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state - + sml::completion - / action::effect_compute_text_sampling_probabilities{} - , sml::state <= sml::state - + sml::completion - / action::effect_compute_text_sampling_top_k{} - , sml::state <= sml::state - + sml::completion - / action::effect_select_text_sampling_token{} , sml::state <= sml::state + sml::completion [ guard::guard_sampled_text_token_ready{} ] / action::effect_publish_sampled_text_token{} @@ -917,21 +902,12 @@ struct model { / action::effect_mark_graph_execution_unsupported{} , sml::state <= sml::state + sml::completion - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_depformer_logits_matmul_succeeded{} ] - / action::effect_scale_depformer_sampling_logits{} + / action::effect_select_depformer_sampling_token{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_logits_matmul_failed{} ] / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state - + sml::completion - / action::effect_compute_depformer_sampling_probabilities{} - , sml::state <= sml::state - + sml::completion - / action::effect_compute_depformer_sampling_top_k{} - , sml::state <= sml::state - + sml::completion - / action::effect_select_depformer_sampling_token{} , sml::state <= sml::state + sml::completion [ guard::guard_depformer_layer_norm_supported{} ] / action::effect_run_depformer_layer_norm_rms{} diff --git a/tests/logits/sampler/pipeline_tests.cpp b/tests/logits/sampler/pipeline_tests.cpp index 1a941bf5..849b1660 100644 --- a/tests/logits/sampler/pipeline_tests.cpp +++ b/tests/logits/sampler/pipeline_tests.cpp @@ -362,3 +362,32 @@ TEST_CASE("sampler pipeline propagates gbnf sampler errors") { CHECK(err == emel::error::cast(emel::gbnf::sampler::error::invalid_request)); CHECK(selected == -1); } + +TEST_CASE("sampler rejects invalid typed temperature top-k workspace") { + std::array logits = {1.0f, 2.0f}; + std::array sorted_indices = {}; + std::array top_probabilities = {}; + std::array top_indices = {}; + uint32_t random_state = 1234u; + int32_t selected = -1; + float score = 0.0f; + emel::error::type err = emel::error::cast(emel::logits::sampler::error::none); + emel::logits::sampler::event::sample_temperature_top_k request{ + logits, + 2, + 0.8f, + 1, + sorted_indices, + top_probabilities, + top_indices, + random_state, + selected, + score, + err}; + emel::logits::sampler::sm machine{}; + + CHECK_FALSE(machine.process_event(request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(selected == -1); +} diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index e7e0d131..4b27fd1a 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -10,6 +10,7 @@ #include #include "../../memory/recording_kv_actor.hpp" +#include "emel/logits/sampler/sm.hpp" #include "emel/memory/streaming/sm.hpp" #include "emel/model/moshi/detail.hpp" #include "emel/speech/predictor/moshi/any.hpp" @@ -29,23 +30,28 @@ using emel::speech::predictor::moshi::test::repo_root; inline constexpr emel::error::type k_no_error = emel::error::cast(moshi::error::none); -moshi_executor::dependencies -make_executor_dependencies(emel::kernel::sm &kernel, - const moshi_executor::kv_views &kv = {}) noexcept { +moshi_executor::dependencies make_executor_dependencies( + emel::kernel::sm &kernel, const moshi_executor::kv_views &kv = {}, + emel::logits::sampler::sm *sampler = nullptr) noexcept { return moshi_executor::dependencies{ .kv = kv, .kernel = kernel, - .policy = moshi_executor::action::policies{ - .rms_norm_epsilon = 1.0e-8f, - .zero_seed_state = 123459876u, - }, - .capacity = moshi_executor::action::capacities{ - .hidden_dim = moshi_executor::detail::k_max_hidden_dim, - .temporal_context = moshi_executor::detail::k_max_temporal_context, - .depformer_context = moshi_executor::detail::k_max_depformer_context, - .sampling_card = moshi_executor::detail::k_max_sampling_card, - .sampling_top_k = moshi_executor::detail::k_max_sampling_top_k, - }, + .sampler = sampler, + .policy = + moshi_executor::action::policies{ + .rms_norm_epsilon = 1.0e-8f, + .zero_seed_state = 123459876u, + }, + .capacity = + moshi_executor::action::capacities{ + .hidden_dim = moshi_executor::detail::k_max_hidden_dim, + .temporal_context = + moshi_executor::detail::k_max_temporal_context, + .depformer_context = + moshi_executor::detail::k_max_depformer_context, + .sampling_card = moshi_executor::detail::k_max_sampling_card, + .sampling_top_k = moshi_executor::detail::k_max_sampling_top_k, + }, }; } @@ -822,7 +828,8 @@ TEST_CASE("speech_moshi_executor_initializes_lm_fixture") { } emel::kernel::sm kernel{}; - moshi_executor::sm executor{make_executor_dependencies(kernel)}; + emel::logits::sampler::sm sampler{}; + moshi_executor::sm executor{make_executor_dependencies(kernel, {}, &sampler)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -873,7 +880,8 @@ TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { } emel::kernel::sm kernel{}; - moshi_executor::sm executor{make_executor_dependencies(kernel)}; + emel::logits::sampler::sm sampler{}; + moshi_executor::sm executor{make_executor_dependencies(kernel, {}, &sampler)}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.sampling_enabled = true; @@ -888,6 +896,28 @@ TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { CHECK(err == emel::error::cast(moshi_executor::error::none)); } +TEST_CASE("speech_moshi_executor_requires_sampler_for_sampling") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::kernel::sm kernel{}; + moshi_executor::sm executor{make_executor_dependencies(kernel)}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.sampling_enabled = true; + init.sampling_audio_temperature = 0.8f; + init.sampling_text_temperature = 0.7f; + init.sampling_audio_top_k = 250; + init.sampling_text_top_k = 25; + init.sampling_seed = 1234u; + init.error_out = &err; + + CHECK_FALSE(executor.process_event(init)); + CHECK(err == emel::error::cast(moshi_executor::error::bind_failed)); +} + TEST_CASE("speech_moshi_executor_sampling_matches_reference_probability_path") { std::array logits = {}; uint32_t logit_state = 1153427707u; @@ -903,13 +933,23 @@ TEST_CASE("speech_moshi_executor_sampling_matches_reference_probability_path") { int32_t best_index = -1; float best_score = 0.0f; - moshi_executor::detail::scale_sampling_logits(logits, 2048, 0.8f); - moshi_executor::detail::compute_sampling_probabilities(logits, 2048); - moshi_executor::detail::compute_sampling_top_k( - logits, sorted_indices, top_probabilities, top_indices, 2048, 250); - moshi_executor::detail::compute_sampling_exponential_argmax( - top_probabilities, top_indices, 2048, 250, random_state, best_index, - best_score); + emel::logits::sampler::sm sampler{}; + emel::error::type err = emel::error::cast(emel::logits::sampler::error::none); + emel::logits::sampler::event::sample_temperature_top_k request{ + logits, + 2048, + 0.8f, + 250, + sorted_indices, + top_probabilities, + top_indices, + random_state, + best_index, + best_score, + err}; + + REQUIRE(sampler.process_event(request)); + CHECK(err == emel::error::cast(emel::logits::sampler::error::none)); CHECK(best_index == 1582); CHECK(random_state == 1237704734u); @@ -1897,6 +1937,8 @@ TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { initialize_streaming_position(second_depformer_positions); emel::kernel::sm first_kernel{}; emel::kernel::sm second_kernel{}; + emel::logits::sampler::sm first_sampler{}; + emel::logits::sampler::sm second_sampler{}; const auto first_views = prepare_kv_views(*first_fixture.model, &first_temporal, &first_depformer, &first_temporal_positions, &first_depformer_positions); @@ -1904,9 +1946,9 @@ TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { *second_fixture.model, &second_temporal, &second_depformer, &second_temporal_positions, &second_depformer_positions); moshi_executor::sm first{ - make_executor_dependencies(first_kernel, first_views)}; + make_executor_dependencies(first_kernel, first_views, &first_sampler)}; moshi_executor::sm second{ - make_executor_dependencies(second_kernel, second_views)}; + make_executor_dependencies(second_kernel, second_views, &second_sampler)}; emel::error::type first_err = emel::error::cast(moshi_executor::error::none); emel::error::type second_err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize first_init{*first_fixture.model}; diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index d41a35a1..70529adf 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -517,6 +517,7 @@ int main(int argc, char **argv) { }, }; emel::kernel::sm prediction_kernel{}; + emel::logits::sampler::sm prediction_sampler{}; runtime::sm prediction_runtime{runtime::dependencies{ .kv = runtime::kv_views{ @@ -526,6 +527,7 @@ int main(int argc, char **argv) { .depformer_positions = &secondary_positions, }, .kernel = prediction_kernel, + .sampler = &prediction_sampler, .policy = runtime::action::policies{ .rms_norm_epsilon = 1.0e-8f, From f416582317986e4193fd3da9144efd16f190a2bd Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 22:42:03 -0500 Subject: [PATCH 27/61] refactor: inject moshi token sentinels --- CMakeLists.txt | 1 + src/emel/speech/predictor/moshi/actions.hpp | 12 +- src/emel/speech/predictor/moshi/context.hpp | 14 +- src/emel/speech/predictor/moshi/events.hpp | 2 +- .../predictor/moshi/executor/context.hpp | 1 + .../predictor/moshi/executor/detail.hpp | 7 +- .../predictor/moshi/executor/events.hpp | 2 +- .../predictor/moshi/executor/guards.hpp | 26 ++-- src/emel/speech/predictor/moshi/guards.hpp | 5 +- src/emel/speech/predictor/moshi/sm.hpp | 2 +- .../predictor/moshi_executor_detail_tests.cpp | 130 ++++++++++++++++++ .../moshi_executor_streaming_tests.cpp | 1 + .../predictor/moshi_lifecycle_tests.cpp | 95 ++++++++++--- .../bench/speech/personaplex_emel_runner.cpp | 6 + 14 files changed, 255 insertions(+), 49 deletions(-) create mode 100644 tests/speech/predictor/moshi_executor_detail_tests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2750ec7b..e10c8bff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,7 @@ if(EMEL_ENABLE_TESTS) tests/speech/codec/mimi_lifecycle_tests.cpp tests/speech/generator/lifecycle_tests.cpp tests/speech/predictor/moshi_lifecycle_tests.cpp + tests/speech/predictor/moshi_executor_detail_tests.cpp tests/speech/predictor/moshi_executor_streaming_tests.cpp tests/speech/encoder/whisper/lifecycle_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index d66e2f9a..33ac4317 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -111,7 +111,7 @@ struct effect_bind_contract { ctx.lmgen.generated_dep_q = lm.dep_q; ctx.lmgen.cache_row_count = 2; std::fill(ctx.lmgen.cache.begin(), ctx.lmgen.cache.end(), - k_token_ungenerated); + ctx.policy.token_ungenerated); std::fill(ctx.lmgen.initial.begin(), ctx.lmgen.initial.end(), lm.card); ctx.lmgen.initial[0] = lm.text_card; for (uint32_t index = 0; index < lm.delay_count; ++index) { @@ -274,11 +274,11 @@ struct effect_begin_voice_prefill { ctx.voice.prompt_frame_count - ctx.voice.prompt_frame_index; runtime_ev.ctx.text_token = ctx.session.model->moshi_lm.text_padding_id; std::fill(runtime_ev.ctx.input_sequence.begin(), - runtime_ev.ctx.input_sequence.end(), k_token_zero); + runtime_ev.ctx.input_sequence.end(), ctx.policy.token_zero); runtime_ev.ctx.input_sequence[0] = ctx.session.model->moshi_lm.text_padding_id; std::fill(runtime_ev.ctx.audio_tokens.begin(), - runtime_ev.ctx.audio_tokens.end(), k_token_zero); + runtime_ev.ctx.audio_tokens.end(), ctx.policy.token_zero); } }; @@ -462,11 +462,11 @@ struct effect_begin_personaplex_prompt_prefill { ctx.voice.post_text_silence_remaining; runtime_ev.ctx.text_token = ctx.session.model->moshi_lm.text_padding_id; std::fill(runtime_ev.ctx.prompt_sequence.begin(), - runtime_ev.ctx.prompt_sequence.end(), k_token_zero); + runtime_ev.ctx.prompt_sequence.end(), ctx.policy.token_zero); std::fill(runtime_ev.ctx.input_sequence.begin(), - runtime_ev.ctx.input_sequence.end(), k_token_zero); + runtime_ev.ctx.input_sequence.end(), ctx.policy.token_zero); std::fill(runtime_ev.ctx.audio_tokens.begin(), - runtime_ev.ctx.audio_tokens.end(), k_token_zero); + runtime_ev.ctx.audio_tokens.end(), ctx.policy.token_zero); } }; diff --git a/src/emel/speech/predictor/moshi/context.hpp b/src/emel/speech/predictor/moshi/context.hpp index 5aedabee..ddfbd0d5 100644 --- a/src/emel/speech/predictor/moshi/context.hpp +++ b/src/emel/speech/predictor/moshi/context.hpp @@ -14,8 +14,11 @@ namespace emel::speech::predictor::moshi::action { inline constexpr int32_t k_max_codebooks = static_cast(event::k_max_codebooks); inline constexpr int32_t k_max_delay_rows = 128; -inline constexpr int32_t k_token_zero = -1; -inline constexpr int32_t k_token_ungenerated = -2; + +struct policies { + int32_t token_zero = 0; + int32_t token_ungenerated = 0; +}; struct lmgen_state { int32_t codebook_count = 0; @@ -62,17 +65,20 @@ struct voice_prompt_state { template struct dependencies { emel::memory::hybrid::kv_binding kv_cache = {}; graph_actor_type &graph; + policies policy = {}; }; struct context { context() = default; - explicit context(const emel::memory::hybrid::kv_binding &kv_cache) - : memory(kv_cache) {} + template + explicit context(const dependencies &deps) + : memory(deps.kv_cache), policy(deps.policy) {} runtime session = {}; voice_prompt_state voice = {}; lmgen_state lmgen = {}; emel::memory::hybrid::sm memory = {}; + const policies policy = {}; }; } // namespace emel::speech::predictor::moshi::action diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 3ec2514c..4c58ad43 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -48,7 +48,7 @@ struct initialize { float sampling_text_temperature = 0.0f; int32_t sampling_audio_top_k = 0; int32_t sampling_text_top_k = 0; - uint32_t sampling_seed = 1u; + uint32_t sampling_seed = 0u; emel::error::type *error_out = nullptr; emel::callback on_done = {}; emel::callback on_error = {}; diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index cd779207..d6d69f05 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -22,6 +22,7 @@ struct kv_views { struct policies { float rms_norm_epsilon = 0.0f; uint32_t zero_seed_state = 0u; + int32_t token_zero = 0; }; struct capacities { diff --git a/src/emel/speech/predictor/moshi/executor/detail.hpp b/src/emel/speech/predictor/moshi/executor/detail.hpp index ec3ae9bd..4bfa9d51 100644 --- a/src/emel/speech/predictor/moshi/executor/detail.hpp +++ b/src/emel/speech/predictor/moshi/executor/detail.hpp @@ -26,7 +26,6 @@ inline constexpr uint64_t k_max_temporal_context = 8192u; inline constexpr uint64_t k_max_depformer_context = 512u; inline constexpr uint64_t k_max_sampling_card = 65536u; inline constexpr uint64_t k_max_sampling_top_k = 1024u; -inline constexpr int32_t k_token_zero = -1; struct streaming_kv_view { std::span key_cache = {}; @@ -274,9 +273,9 @@ inline bool tensor_shape(const tensor_record *tensor, const int64_t ne0, (tensor->n_dims == 1 || tensor->dims[1] == ne1); } -inline bool token_in_embedding_range(const int32_t token, - const int32_t card) noexcept { - return token >= k_token_zero && token <= card; +inline bool token_in_embedding_range(const int32_t token, const int32_t card, + const int32_t token_zero) noexcept { + return token >= token_zero && token <= card; } } // namespace emel::speech::predictor::moshi::executor::detail diff --git a/src/emel/speech/predictor/moshi/executor/events.hpp b/src/emel/speech/predictor/moshi/executor/events.hpp index f92c2925..8f4115ca 100644 --- a/src/emel/speech/predictor/moshi/executor/events.hpp +++ b/src/emel/speech/predictor/moshi/executor/events.hpp @@ -30,7 +30,7 @@ struct initialize { float sampling_text_temperature = 0.0f; int32_t sampling_audio_top_k = 0; int32_t sampling_text_top_k = 0; - uint32_t sampling_seed = 1u; + uint32_t sampling_seed = 0u; emel::error::type *error_out = nullptr; emel::callback on_done = {}; emel::callback on_error = {}; diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 8682f7a3..66ca04e7 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -23,7 +23,8 @@ struct guard_bind_contract_valid { model.moshi_lm.dim > 0 && (!runtime_ev.request.sampling_enabled || ctx.sampler != nullptr) && ctx.policy.rms_norm_epsilon > 0.0f && - ctx.policy.zero_seed_state != 0u && ctx.capacity.hidden_dim > 0u && + ctx.policy.zero_seed_state != 0u && ctx.policy.token_zero < 0 && + ctx.capacity.hidden_dim > 0u && ctx.capacity.hidden_dim <= detail::k_max_hidden_dim && ctx.capacity.temporal_context > 0u && ctx.capacity.temporal_context <= detail::k_max_temporal_context && @@ -156,15 +157,15 @@ struct guard_token_input_embedding_supported { static_cast(audio_emb->type)); } bool tokens_ok = - runtime_ev.request.input_sequence[0] != detail::k_token_zero && + runtime_ev.request.input_sequence[0] != ctx.policy.token_zero && detail::token_in_embedding_range(runtime_ev.request.input_sequence[0], - lm.text_card); + lm.text_card, ctx.policy.token_zero); for (int32_t index = 0; index < lm.n_q; ++index) { tokens_ok = tokens_ok && detail::token_in_embedding_range( runtime_ev.request.input_sequence[static_cast(index + 1)], - lm.card); + lm.card, ctx.policy.token_zero); } return runtime_ev.request.input_embedding.data() == nullptr && !lm.demux_second_stream && hidden_dim > 0 && @@ -262,8 +263,9 @@ struct guard_current_input_audio_token_present { } const int32_t token = runtime_ev.request.input_sequence[static_cast(index + 1)]; - return token != detail::k_token_zero && - detail::token_in_embedding_range(token, lm.card) && + return token != ctx.policy.token_zero && + detail::token_in_embedding_range(token, lm.card, + ctx.policy.token_zero) && guard_input_embedding_supported{}(runtime_ev, ctx); } }; @@ -277,7 +279,7 @@ struct guard_current_input_audio_token_zero { return false; } return runtime_ev.request.input_sequence[static_cast(index + 1)] == - detail::k_token_zero && + ctx.policy.token_zero && guard_input_embedding_supported{}(runtime_ev, ctx); } }; @@ -973,11 +975,12 @@ struct guard_text_logits_unsupported { struct guard_forced_text_token_valid { bool operator()(const event::step_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { return runtime_ev.request.forced_text_token >= 0 && detail::token_in_embedding_range( runtime_ev.request.forced_text_token, - runtime_ev.request.model.moshi_lm.text_card); + runtime_ev.request.model.moshi_lm.text_card, + ctx.policy.token_zero); } }; @@ -1270,7 +1273,8 @@ struct guard_depformer_text_input_supported { detail::supported_get_rows_dtype( static_cast(embedding->type)) && detail::token_in_embedding_range(runtime_ev.request.text_token_out, - lm.text_card); + lm.text_card, + ctx.policy.token_zero); } }; @@ -1306,7 +1310,7 @@ struct guard_depformer_audio_input_supported { detail::token_in_embedding_range( runtime_ev.request .audio_tokens_out[static_cast(codebook - 1)], - lm.card); + lm.card, ctx.policy.token_zero); } }; diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index b5e25c5a..0dc15891 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -12,7 +12,7 @@ namespace emel::speech::predictor::moshi::guard { struct guard_bind_contract_valid { bool operator()(const event::initialize_run &runtime_ev, - const action::context &) const noexcept { + const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; int32_t max_delay = 0; @@ -49,7 +49,8 @@ struct guard_bind_contract_valid { runtime_ev.request.codebook_capacity <= action::k_max_codebooks && runtime_ev.request.delay_cache_row_capacity >= row_count && runtime_ev.request.delay_cache_row_capacity <= - action::k_max_delay_rows; + action::k_max_delay_rows && + ctx.policy.token_ungenerated < ctx.policy.token_zero; } }; diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 8a28b7d7..453f555e 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -648,7 +648,7 @@ struct sm : public emel::sm, action::context> { using base_type::visit_current_states; explicit sm(const action::dependencies &deps) - : base_type(std::piecewise_construct, deps.kv_cache, deps.graph), + : base_type(std::piecewise_construct, deps, deps.graph), memory_snapshot_(std::make_unique()) {} sm(const sm &) = delete; diff --git a/tests/speech/predictor/moshi_executor_detail_tests.cpp b/tests/speech/predictor/moshi_executor_detail_tests.cpp new file mode 100644 index 00000000..ab5436d6 --- /dev/null +++ b/tests/speech/predictor/moshi_executor_detail_tests.cpp @@ -0,0 +1,130 @@ +#include +#include +#include + +#include + +#include "emel/kernel/detail.hpp" +#include "emel/speech/predictor/moshi/executor/detail.hpp" +#include "moshi_fixture.hpp" + +namespace { + +namespace detail = emel::speech::predictor::moshi::executor::detail; +using emel::speech::predictor::moshi::test::load_fixture_or_skip; + +detail::dtype dtype(const uint8_t code) { + return static_cast(code); +} + +} // namespace + +TEST_CASE("speech Moshi executor binds supported dense and quantized views") { + std::array dense_data = {}; + emel::model::data::tensor_record tensor{}; + tensor.data = dense_data.data(); + tensor.n_dims = 2; + tensor.dims[0] = 4; + tensor.dims[1] = 4; + tensor.type = emel::kernel::detail::dtype_f32; + detail::tensor_view view{}; + + REQUIRE(detail::bind_tensor_view(tensor, view)); + CHECK(view.data == dense_data.data()); + CHECK(view.ne[0] == 4u); + CHECK(view.ne[1] == 4u); + CHECK(view.nb[0] == sizeof(float)); + + std::array quantized_data = {}; + tensor.data = quantized_data.data(); + tensor.dims[0] = 32; + tensor.dims[1] = 2; + tensor.type = emel::kernel::detail::dtype_q4_0; + REQUIRE(detail::bind_tensor_view(tensor, view)); + CHECK(view.nb[0] == 1u); + CHECK(view.nb[1] > 0u); + + tensor.type = emel::kernel::detail::dtype_q4_k_x8_bl4; + tensor.dims[0] = 256; + tensor.dims[1] = 8; + REQUIRE(detail::bind_tensor_view(tensor, view)); + CHECK(view.nb[1] > 0u); + CHECK(view.nb[2] > 0u); + + tensor.dims[0] = 255; + CHECK_FALSE(detail::bind_tensor_view(tensor, view)); + + tensor.type = emel::kernel::detail::dtype_q4_0; + tensor.dims[0] = 1; + tensor.dims[1] = 2; + CHECK_FALSE(detail::bind_tensor_view(tensor, view)); + + tensor.data = nullptr; + CHECK_FALSE(detail::bind_tensor_view(tensor, view)); +} + +TEST_CASE("speech Moshi executor classifies supported operand dtypes") { + CHECK( + detail::supported_get_rows_dtype(dtype(emel::kernel::detail::dtype_f32))); + CHECK( + detail::supported_get_rows_dtype(dtype(emel::kernel::detail::dtype_f16))); + CHECK(detail::supported_get_rows_dtype( + dtype(emel::kernel::detail::dtype_bf16))); + CHECK(detail::supported_get_rows_dtype( + dtype(emel::kernel::detail::dtype_q4_0))); + CHECK(detail::supported_get_rows_dtype( + dtype(emel::kernel::detail::dtype_q8_0))); + CHECK(detail::supported_get_rows_dtype( + dtype(emel::kernel::detail::dtype_q4_k))); + CHECK_FALSE( + detail::supported_get_rows_dtype(dtype(emel::kernel::detail::dtype_i32))); + + CHECK( + detail::supported_argmax_dtype(dtype(emel::kernel::detail::dtype_q4_k))); + CHECK(detail::supported_argmax_dtype( + dtype(emel::kernel::detail::dtype_q4_k_x8_bl4))); + CHECK_FALSE( + detail::supported_argmax_dtype(dtype(emel::kernel::detail::dtype_i32))); + + CHECK( + detail::supported_mul_mat_dtype(dtype(emel::kernel::detail::dtype_f16))); + CHECK( + detail::supported_mul_mat_dtype(dtype(emel::kernel::detail::dtype_q8_0))); + CHECK(detail::supported_mul_mat_dtype( + dtype(emel::kernel::detail::dtype_q4_k_x8_bl8))); + CHECK_FALSE( + detail::supported_mul_mat_dtype(dtype(emel::kernel::detail::dtype_i32))); +} + +TEST_CASE("speech Moshi executor resolves model tensor families") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + const auto &model = *fixture.model; + CHECK(detail::find_tensor(model, "lm.text_emb.weight") != nullptr); + CHECK(detail::find_tensor(model, "missing.tensor") == nullptr); + CHECK(detail::find_indexed_tensor(model, "lm.emb.%d.weight", 0) != nullptr); + CHECK(detail::find_lm_transformer_projection(model, 0) != nullptr); + CHECK(detail::find_depformer_projection(model, 0, 0) != nullptr); + CHECK(detail::find_depformer_codebook_tensor( + model, 0, "self_attn.in_projs.%d.weight", 0) != nullptr); + + const std::array long_name = [] { + std::array value{}; + value.fill('x'); + value.back() = '\0'; + return value; + }(); + CHECK(detail::find_indexed_tensor(model, long_name.data(), 0) == nullptr); + CHECK(detail::find_lm_transformer_tensor(model, 0, long_name.data()) == + nullptr); + CHECK(detail::find_depformer_tensor(model, 0, long_name.data()) == nullptr); + CHECK(detail::find_depformer_codebook_tensor(model, 0, long_name.data(), 0) == + nullptr); + + auto empty_model = std::make_unique(); + CHECK(detail::find_lm_transformer_projection(*empty_model, 0) == nullptr); + CHECK(detail::find_depformer_projection(*empty_model, 0, 0) == nullptr); +} diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index 8225cd95..9103f4d6 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -108,6 +108,7 @@ TEST_CASE( executor::action::policies{ .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, + .token_zero = -1, }, .capacity = executor::action::capacities{ diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 4b27fd1a..77c4ac4a 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -41,6 +41,7 @@ moshi_executor::dependencies make_executor_dependencies( moshi_executor::action::policies{ .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, + .token_zero = -1, }, .capacity = moshi_executor::action::capacities{ @@ -55,6 +56,21 @@ moshi_executor::dependencies make_executor_dependencies( }; } +template +moshi::action::dependencies make_predictor_dependencies( + graph_actor_type &graph, + const emel::memory::hybrid::kv_binding &kv_cache = {}) noexcept { + return moshi::action::dependencies{ + .kv_cache = kv_cache, + .graph = graph, + .policy = + moshi::action::policies{ + .token_zero = -1, + .token_ungenerated = -2, + }, + }; +} + void configure_predictor_initialize(moshi::event::initialize &request) { int32_t maximum_delay = 0; for (uint32_t index = 0; index < request.model.moshi_lm.delay_count; @@ -358,7 +374,7 @@ void initialize_streaming_position(memory_streaming::sm &position) { TEST_CASE("speech_moshi_predictor_rejects_predict_before_initialize") { recording_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{.graph = graph}}; + moshi::sm generator{make_predictor_dependencies(graph)}; std::array input = {0, 0, 0, 0}; moshi::event::predict::workspace workspace{}; emel::error::type err = k_no_error; @@ -374,7 +390,7 @@ TEST_CASE("speech_moshi_generator_rejects_non_lm_model_contract") { auto model = std::make_unique(); model->moshi_component_id = emel::model::data::moshi_component::mimi; recording_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{.graph = graph}}; + moshi::sm generator{make_predictor_dependencies(graph)}; emel::error::type err = k_no_error; moshi::event::initialize init{*model}; @@ -394,8 +410,8 @@ TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { emel::memory::test::recording_kv_actor kv{}; recording_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{ - .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; + moshi::sm generator{make_predictor_dependencies( + graph, emel::memory::hybrid::bind_kv_actor(kv))}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -417,10 +433,27 @@ TEST_CASE("speech_moshi_predictor_rejects_missing_initialize_capacity") { return; } + recording_graph_executor graph{}; + moshi::sm generator{make_predictor_dependencies(graph)}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*fixture.model}; + init.error_out = &err; + + CHECK_FALSE(generator.process_event(init)); + CHECK(err == emel::error::cast(moshi::error::bind_failed)); +} + +TEST_CASE("speech_moshi_predictor_rejects_missing_token_policy") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + recording_graph_executor graph{}; moshi::sm generator{moshi::action::dependencies{.graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); init.error_out = &err; CHECK_FALSE(generator.process_event(init)); @@ -469,8 +502,8 @@ TEST_CASE( emel::memory::test::recording_kv_actor kv{}; recording_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{ - .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; + moshi::sm generator{make_predictor_dependencies( + graph, emel::memory::hybrid::bind_kv_actor(kv))}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -564,8 +597,8 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" emel::memory::test::recording_kv_actor kv{}; recording_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{ - .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; + moshi::sm generator{make_predictor_dependencies( + graph, emel::memory::hybrid::bind_kv_actor(kv))}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -683,8 +716,8 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" emel::memory::test::recording_kv_actor kv{}; recording_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{ - .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; + moshi::sm generator{make_predictor_dependencies( + graph, emel::memory::hybrid::bind_kv_actor(kv))}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -786,8 +819,8 @@ TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { emel::memory::test::recording_kv_actor kv{}; rejecting_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{ - .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = graph}}; + moshi::sm generator{make_predictor_dependencies( + graph, emel::memory::hybrid::bind_kv_actor(kv))}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); @@ -1218,6 +1251,10 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { std::span{generator_input.data(), 1}, generator_workspace}; moshi::event::predict_run generator_predict_run{generator_predict, generator_predict_ctx}; + moshi::action::effect_mark_not_initialized{}( + generator_predict_run, generator_ctx); + CHECK(generator_predict_ctx.err == + emel::error::cast(moshi::error::not_initialized)); moshi::action::effect_mark_memory_error{}( generator_predict_run, generator_ctx); CHECK(generator_predict_ctx.err == emel::error::cast(moshi::error::memory)); @@ -1233,8 +1270,21 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { moshi::event::predict_run>{}(generator_predict_run, generator_ctx); CHECK(generator_predict_ctx.err == emel::error::cast(moshi::error::personaplex_prompt)); + emel::error::type unexpected_err = k_no_error; + generator_predict.error_out = &unexpected_err; + moshi::action::effect_mark_unexpected{}(generator_predict_run, generator_ctx); + CHECK(generator_predict_ctx.err == + emel::error::cast(moshi::error::unexpected_event)); + moshi::action::effect_mark_unexpected_and_store{}(generator_predict_run, + generator_ctx); + CHECK(unexpected_err == emel::error::cast(moshi::error::unexpected_event)); CHECK(moshi::guard::guard_memory_rejected{}(generator_predict_run, generator_ctx)); + CHECK(moshi::guard::guard_standard_lmgen{}(init_run, generator_ctx) != + moshi::guard::guard_personaplex_lmgen{}(init_run, generator_ctx)); + CHECK(moshi::guard::guard_graph_initialize_failed{}(init_run, generator_ctx)); + CHECK(moshi::guard::guard_predict_request_shape_invalid{}( + generator_predict_run, generator_ctx)); moshi::event::begin_personaplex_prompt begin_prompt{}; moshi::event::begin_personaplex_prompt_ctx begin_prompt_ctx{}; @@ -1292,6 +1342,8 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { moshi::event::load_voice load_voice{*fixture.model}; moshi::event::load_voice_ctx load_voice_ctx{}; moshi::event::load_voice_run load_voice_run{load_voice, load_voice_ctx}; + CHECK(moshi::guard::guard_voice_contract_invalid{}(load_voice_run, + generator_ctx)); load_voice.on_done = emel::callback::from< moshi_callback_probe, @@ -1417,10 +1469,13 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { snapshot.sequence_kv_block_count[0] = 1; snapshot.sequence_kv_blocks[0][0] = 0; + emel::kernel::sm guard_kernel{}; + moshi_executor::action::context executor_ctx{ + make_executor_dependencies(guard_kernel)}; std::array input = {}; std::array output = {}; std::array embedding = {}; - input.fill(moshi_executor::detail::k_token_zero); + input.fill(executor_ctx.policy.token_zero); input[0] = lm.text_padding_id; input[1] = 0; int32_t text_token = -1; @@ -1433,9 +1488,6 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { std::span{embedding.data(), static_cast(lm.dim)}; moshi_executor::event::step_ctx step_ctx{}; moshi_executor::event::step_run step_run{step, step_ctx}; - emel::kernel::sm guard_kernel{}; - moshi_executor::action::context executor_ctx{ - make_executor_dependencies(guard_kernel)}; executor_ctx.session.model = fixture.model.get(); executor_ctx.session.codebook_count = lm.n_q + 1; executor_ctx.session.dep_q = lm.dep_q; @@ -1540,10 +1592,15 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { CHECK(moshi_executor::guard::guard_projection_view_bound{}(step_run, executor_ctx)); + step_ctx.input_audio_codebook_index = -1; + CHECK_FALSE(moshi_executor::guard::guard_current_input_audio_token_present{}( + step_run, executor_ctx)); + CHECK_FALSE(moshi_executor::guard::guard_current_input_audio_token_zero{}( + step_run, executor_ctx)); step_ctx.input_audio_codebook_index = 0; CHECK(moshi_executor::guard::guard_current_input_audio_token_present{}( step_run, executor_ctx)); - input[1] = moshi_executor::detail::k_token_zero; + input[1] = executor_ctx.policy.token_zero; CHECK(moshi_executor::guard::guard_current_input_audio_token_zero{}( step_run, executor_ctx)); step.input_embedding = {}; @@ -2015,8 +2072,8 @@ TEST_CASE( emel::kernel::sm kernel{}; moshi_executor::sm executor{make_executor_dependencies(kernel)}; - moshi::sm generator{moshi::action::dependencies{ - .kv_cache = emel::memory::hybrid::bind_kv_actor(kv), .graph = executor}}; + moshi::sm generator{make_predictor_dependencies( + executor, emel::memory::hybrid::bind_kv_actor(kv))}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 70529adf..3bb1776a 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -532,6 +532,7 @@ int main(int argc, char **argv) { runtime::action::policies{ .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, + .token_zero = -1, }, .capacity = runtime::action::capacities{ @@ -552,6 +553,11 @@ int main(int argc, char **argv) { predictor::sm token_predictor{predictor::action::dependencies{ .kv_cache = emel::memory::hybrid::kv_binding{}, .graph = prediction_runtime, + .policy = + predictor::action::policies{ + .token_zero = -1, + .token_ungenerated = -2, + }, }}; predictor::event::predict::workspace prediction_workspace{}; tokenizer::sm token_delay{tokenizer::dependencies{ From 6ca2cf0ad58e5dc4d84bd1f831db291498bc20d4 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 22:50:59 -0500 Subject: [PATCH 28/61] refactor: expose personaplex benchmark contracts --- src/emel/speech/generator/any.hpp | 7 ++++++ src/emel/speech/predictor/moshi/any.hpp | 9 ++++++++ .../speech/predictor/moshi/executor/any.hpp | 2 ++ tools/bench/bench_dependency_manifest.cpp | 4 ++++ tools/bench/bench_runner_tests.cpp | 10 ++++++++ tools/bench/dependency_manifest.txt | 1 + .../bench/speech/personaplex_emel_runner.cpp | 23 +++++++++---------- 7 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/emel/speech/generator/any.hpp b/src/emel/speech/generator/any.hpp index 8ec950ca..c2f68a04 100644 --- a/src/emel/speech/generator/any.hpp +++ b/src/emel/speech/generator/any.hpp @@ -1,3 +1,10 @@ #pragma once #include "emel/speech/generator/sm.hpp" + +namespace emel::speech::generator { + +using duplex = action::mode::duplex; +using synthesis = action::mode::synthesis; + +} // namespace emel::speech::generator diff --git a/src/emel/speech/predictor/moshi/any.hpp b/src/emel/speech/predictor/moshi/any.hpp index 206b6625..eb3d7174 100644 --- a/src/emel/speech/predictor/moshi/any.hpp +++ b/src/emel/speech/predictor/moshi/any.hpp @@ -1,3 +1,12 @@ #pragma once #include "emel/speech/predictor/moshi/sm.hpp" + +namespace emel::speech::predictor::moshi { + +using policies = action::policies; + +template +using dependencies = action::dependencies; + +} // namespace emel::speech::predictor::moshi diff --git a/src/emel/speech/predictor/moshi/executor/any.hpp b/src/emel/speech/predictor/moshi/executor/any.hpp index 01ef1777..5c21a728 100644 --- a/src/emel/speech/predictor/moshi/executor/any.hpp +++ b/src/emel/speech/predictor/moshi/executor/any.hpp @@ -6,5 +6,7 @@ namespace emel::speech::predictor::moshi::executor { using kv_views = action::kv_views; using dependencies = action::dependencies; +using policies = action::policies; +using capacities = action::capacities; } // namespace emel::speech::predictor::moshi::executor diff --git a/tools/bench/bench_dependency_manifest.cpp b/tools/bench/bench_dependency_manifest.cpp index 216d2042..2389331f 100644 --- a/tools/bench/bench_dependency_manifest.cpp +++ b/tools/bench/bench_dependency_manifest.cpp @@ -400,6 +400,10 @@ constexpr std::array k_records{ kind::source, "tools/bench/speech/lm_moshi_bench.cpp", "suite_source"}, + dependency_record{"speech_lm_moshi", + kind::source, + "tools/bench/speech/personaplex_emel_runner.cpp", + "e2e_emel_lane_runner"}, dependency_record{"speech_lm_moshi", kind::source, "src/emel/model/moshi", diff --git a/tools/bench/bench_runner_tests.cpp b/tools/bench/bench_runner_tests.cpp index b037cf5a..cff754b8 100644 --- a/tools/bench/bench_runner_tests.cpp +++ b/tools/bench/bench_runner_tests.cpp @@ -1151,6 +1151,7 @@ TEST_CASE( bool has_speech_lm_script = false; bool has_speech_lm_setup = false; bool has_speech_lm_moshi_binding = false; + bool has_personaplex_emel_runner = false; for (const auto &record : speech_lm_records) { has_speech_lm_script = has_speech_lm_script || record.path == "scripts/bench_moshi_lm_compare.sh"; @@ -1160,10 +1161,15 @@ TEST_CASE( has_speech_lm_moshi_binding = has_speech_lm_moshi_binding || record.path == std::string_view{"src/emel/model/moshi"}; + has_personaplex_emel_runner = + has_personaplex_emel_runner || + record.path == std::string_view{ + "tools/bench/speech/personaplex_emel_runner.cpp"}; } CHECK(has_speech_lm_script); CHECK(has_speech_lm_setup); CHECK(has_speech_lm_moshi_binding); + CHECK(has_personaplex_emel_runner); CHECK(manifest::records_for("missing_runner").empty()); } @@ -1185,6 +1191,10 @@ TEST_CASE( CHECK(rendered.find("record runner=speech_lm_moshi kind=source " "path=tools/bench/speech/lm_moshi_bench.cpp") != std::string::npos); + CHECK(rendered.find( + "record runner=speech_lm_moshi kind=source " + "path=tools/bench/speech/personaplex_emel_runner.cpp") != + std::string::npos); const std::filesystem::path manifest_path = std::filesystem::temp_directory_path() / "emel-bench-runner-tests" / diff --git a/tools/bench/dependency_manifest.txt b/tools/bench/dependency_manifest.txt index 7a4e8ff6..9d7df6f6 100644 --- a/tools/bench/dependency_manifest.txt +++ b/tools/bench/dependency_manifest.txt @@ -107,6 +107,7 @@ record runner=speech_codec_mimi kind=config path=tools/bench/moshi_reference_ref record runner=speech_codec_mimi kind=config path=tools/bench/reference_backends/moshi_cpp_mimi.json reason=reference_backend_descriptor record runner=speech_codec_mimi kind=script path=scripts/setup_moshi_cpp_reference.sh reason=reference_setup record runner=speech_lm_moshi kind=source path=tools/bench/speech/lm_moshi_bench.cpp reason=suite_source +record runner=speech_lm_moshi kind=source path=tools/bench/speech/personaplex_emel_runner.cpp reason=e2e_emel_lane_runner record runner=speech_lm_moshi kind=source path=src/emel/model/moshi reason=model_binding record runner=speech_lm_moshi kind=script path=scripts/bench_moshi_lm_compare.sh reason=compare_wrapper record runner=speech_lm_moshi kind=script path=scripts/setup_moshi_cpp_reference.sh reason=reference_setup diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 3bb1776a..dc190be1 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -22,7 +22,7 @@ #include "emel/model/data.hpp" #include "emel/model/detail.hpp" #include "emel/speech/codec/mimi/any.hpp" -#include "emel/speech/generator/sm.hpp" +#include "emel/speech/generator/any.hpp" #include "emel/speech/predictor/moshi/any.hpp" #include "emel/speech/predictor/moshi/executor/any.hpp" #include "emel/speech/tokenizer/moshi/any.hpp" @@ -78,7 +78,7 @@ struct cache_views { }; struct personaplex_dependencies { - using generator_mode = generator::action::mode::duplex; + using generator_mode = generator::duplex; using voice_condition_event = predictor::event::prefill_voice; using prompt_begin_event = predictor::event::begin_personaplex_prompt; using prompt_condition_event = predictor::event::prefill_personaplex_prompt; @@ -529,13 +529,13 @@ int main(int argc, char **argv) { .kernel = prediction_kernel, .sampler = &prediction_sampler, .policy = - runtime::action::policies{ + runtime::policies{ .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, .token_zero = -1, }, .capacity = - runtime::action::capacities{ + runtime::capacities{ .hidden_dim = static_cast( std::max(lm_model.model->moshi_lm.dim, lm_model.model->moshi_lm.depformer_dim)), @@ -550,11 +550,11 @@ int main(int argc, char **argv) { std::max(config.audio_top_k, config.text_top_k)), }, }}; - predictor::sm token_predictor{predictor::action::dependencies{ + predictor::sm token_predictor{predictor::dependencies{ .kv_cache = emel::memory::hybrid::kv_binding{}, .graph = prediction_runtime, .policy = - predictor::action::policies{ + predictor::policies{ .token_zero = -1, .token_ungenerated = -2, }, @@ -627,8 +627,7 @@ int main(int argc, char **argv) { .codebook_count = public_n_q, }; generator::sm session{dependencies}; - emel::error::type session_err = - generator::action::error_code(generator::error::none); + emel::error::type session_err = emel::error::cast(generator::error::none); if (!session.process_event(generator::event::initialize{session_err})) { std::fprintf(stderr, "PersonaPlex session initialize failed err=%d\n", static_cast(session_err)); @@ -639,7 +638,7 @@ int main(int argc, char **argv) { session.is(stateforward::sml::state)) { bool complete = false; int32_t remaining = -1; - session_err = generator::action::error_code(generator::error::none); + session_err = emel::error::cast(generator::error::none); (void)session.process_event(generator::event::condition{ config.prompt_text_token, complete, remaining, session_err}); } @@ -647,7 +646,7 @@ int main(int argc, char **argv) { session.is(stateforward::sml::state)) { bool complete = false; int32_t remaining = -1; - session_err = generator::action::error_code(generator::error::none); + session_err = emel::error::cast(generator::error::none); (void)session.process_event(generator::event::condition{ config.prompt_text_token, complete, remaining, session_err}); } @@ -664,7 +663,7 @@ int main(int argc, char **argv) { int32_t text_token = -1; bool produced = false; int32_t sample_count = 0; - session_err = generator::action::error_code(generator::error::none); + session_err = emel::error::cast(generator::error::none); generator::event::stream_frame frame{ std::span{pcm_frame}, std::span{output_pcm.data() + frame_index * frame_samples, @@ -701,7 +700,7 @@ int main(int argc, char **argv) { int32_t text_token = -1; int32_t sample_count = 0; bool complete = false; - session_err = generator::action::error_code(generator::error::none); + session_err = emel::error::cast(generator::error::none); generator::event::flush frame{ std::span{output_pcm.data() + frame_index * frame_samples, frame_samples}, From 536b60c2f522dfc928c45cd9b83cec8ab2616e71 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 23:12:37 -0500 Subject: [PATCH 29/61] perf: prebind moshi input embeddings --- snapshots/lint/clang_format.txt | 30 +++-------- src/emel/model/moshi/detail.cpp | 26 ++++++++++ src/emel/model/moshi/detail.hpp | 7 +++ .../predictor/moshi/executor/actions.hpp | 8 +-- .../predictor/moshi/executor/guards.hpp | 50 ++++++++++++------- .../speech/predictor/moshi/executor/sm.hpp | 13 ++++- tests/model/moshi/binding_tests.cpp | 8 +++ .../predictor/moshi_lifecycle_tests.cpp | 10 ++++ 8 files changed, 106 insertions(+), 46 deletions(-) diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index 1bbce937..c31b0508 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -46,9 +46,11 @@ src/emel/diarization/sortformer/executor/guards.hpp src/emel/diarization/sortformer/executor/sm.hpp src/emel/diarization/sortformer/modules/detail.cpp src/emel/diarization/sortformer/modules/detail.hpp +src/emel/diarization/sortformer/output/any.hpp src/emel/diarization/sortformer/output/detail.cpp src/emel/diarization/sortformer/output/detail.hpp src/emel/diarization/sortformer/pipeline/actions.hpp +src/emel/diarization/sortformer/pipeline/any.hpp src/emel/diarization/sortformer/pipeline/context.hpp src/emel/diarization/sortformer/pipeline/detail.hpp src/emel/diarization/sortformer/pipeline/errors.hpp @@ -146,23 +148,6 @@ src/emel/gbnf/sampler/token_parser/errors.hpp src/emel/gbnf/sampler/token_parser/events.hpp src/emel/gbnf/sampler/token_parser/guards.hpp src/emel/gbnf/sampler/token_parser/sm.hpp -src/emel/generator/actions.hpp -src/emel/generator/context.hpp -src/emel/generator/detail.hpp -src/emel/generator/errors.hpp -src/emel/generator/events.hpp -src/emel/generator/guards.hpp -src/emel/generator/initializer/actions.hpp -src/emel/generator/initializer/context.hpp -src/emel/generator/initializer/detail.hpp -src/emel/generator/initializer/guards.hpp -src/emel/generator/initializer/sm.hpp -src/emel/generator/prefill/actions.hpp -src/emel/generator/prefill/context.hpp -src/emel/generator/prefill/detail.hpp -src/emel/generator/prefill/guards.hpp -src/emel/generator/prefill/sm.hpp -src/emel/generator/sm.hpp src/emel/gguf/loader/actions.hpp src/emel/gguf/loader/any.hpp src/emel/gguf/loader/context.hpp @@ -291,7 +276,6 @@ src/emel/kernel/aarch64/context.hpp src/emel/kernel/aarch64/errors.hpp src/emel/kernel/aarch64/events.hpp src/emel/kernel/aarch64/guards.hpp -src/emel/kernel/aarch64/sm.hpp src/emel/kernel/actions.hpp src/emel/kernel/any.hpp src/emel/kernel/context.hpp @@ -346,6 +330,8 @@ src/emel/model/detail.cpp src/emel/model/detail.hpp src/emel/model/gemma4/detail.cpp src/emel/model/gemma4/detail.hpp +src/emel/model/generation/any.cpp +src/emel/model/generation/any.hpp src/emel/model/lfm2/detail.cpp src/emel/model/lfm2/detail.hpp src/emel/model/llama/any.hpp @@ -360,6 +346,7 @@ src/emel/model/omniembed/detail.cpp src/emel/model/omniembed/detail.hpp src/emel/model/qwen3/detail.cpp src/emel/model/qwen3/detail.hpp +src/emel/model/sortformer/any.hpp src/emel/model/sortformer/detail.cpp src/emel/model/sortformer/detail.hpp src/emel/model/tensor/actions.hpp @@ -372,8 +359,6 @@ src/emel/model/tensor/window/guards.hpp src/emel/model/tensor/window/sm.hpp src/emel/sm.hpp src/emel/speech/codec/mimi/any.hpp -src/emel/speech/codec/mimi/detail.cpp -src/emel/speech/codec/mimi/guards.hpp src/emel/speech/decoder/whisper/actions.hpp src/emel/speech/decoder/whisper/any.hpp src/emel/speech/decoder/whisper/context.hpp @@ -618,7 +603,6 @@ tests/memory/kv/lifecycle_tests.cpp tests/memory/recurrent/lifecycle_tests.cpp tests/model/fixture_manifest_tests.cpp tests/model/loader/lifecycle_tests.cpp -tests/model/moshi/binding_tests.cpp tests/model/tensor/lifecycle_tests.cpp tests/model/tensor/window/lifecycle_tests.cpp tests/model/tensor/window/streaming_tests.cpp @@ -627,9 +611,9 @@ tests/sm/callback_tests.cpp tests/sm/sm_any_tests.cpp tests/sm/sm_external_completion_tests.cpp tests/sm/sm_policy_tests.cpp -tests/speech/codec/mimi_lifecycle_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp +tests/speech/predictor/moshi_lifecycle_tests.cpp tests/speech/tokenizer/whisper_tests.cpp tests/tensor/view/lifecycle_tests.cpp tests/text/conditioner/text_conditioner_tests.cpp @@ -645,9 +629,9 @@ tests/text/encoders/ugm_tests.cpp tests/text/encoders/wpm_tests.cpp tests/text/generator/action_guard_tests.cpp tests/text/generator/decode_wavefront/lifecycle_tests.cpp +tests/text/generator/detail_tests.cpp tests/text/generator/determinism_tests.cpp tests/text/generator/initializer/lifecycle_tests.cpp -tests/text/generator/legacy_compatibility_tests.cpp tests/text/generator/lifecycle_tests.cpp tests/text/generator/prefill/lifecycle_tests.cpp tests/text/generator/stream_window_tests.cpp diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index f7efbbd8..2c373dc5 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -644,6 +644,32 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, return emel::error::cast(emel::model::loader::error::model_invalid); } + if (lm.n_q > emel::model::data::moshi_lm_hparams::k_max_delays) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + const auto *text_embedding = find_tensor(model_data, "lm.text_emb.weight"); + contract_out.text_embedding = tensor_view{ + .tensor = text_embedding, + .name = emel::model::tensor_name_view(model_data, *text_embedding), + }; + for (int32_t codebook = 0; codebook < lm.n_q; ++codebook) { + char name[96] = {}; + const int written = + std::snprintf(name, sizeof(name), "lm.emb.%d.weight", codebook); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + const auto *audio_embedding = find_tensor( + model_data, std::string_view{name, static_cast(written)}); + if (audio_embedding == nullptr) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + contract_out.audio_embeddings[static_cast(codebook)] = tensor_view{ + .tensor = audio_embedding, + .name = emel::model::tensor_name_view(model_data, *audio_embedding), + }; + } + for (int32_t block = 0; block < lm.num_layers; ++block) { if (!has_lm_transformer_block(model_data, block)) { return emel::error::cast(emel::model::loader::error::model_invalid); diff --git a/src/emel/model/moshi/detail.hpp b/src/emel/model/moshi/detail.hpp index a27e6da9..f87e301c 100644 --- a/src/emel/model/moshi/detail.hpp +++ b/src/emel/model/moshi/detail.hpp @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include @@ -45,6 +47,11 @@ struct lm_contract { family_view depformer = {}; family_view depformer_text_emb = {}; family_view depformer_emb = {}; + tensor_view text_embedding = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + audio_embeddings = {}; }; struct mimi_contract { diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 65ffa2e7..08c83dbf 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -238,8 +238,7 @@ struct effect_apply_external_input_embedding { struct effect_bind_input_text_embedding { void operator()(const event::step_run &runtime_ev, const context &ctx) const noexcept { - const auto *text_emb = - detail::find_tensor(runtime_ev.request.model, "lm.text_emb.weight"); + const auto *text_emb = ctx.session.contract.lm.text_embedding.tensor; runtime_ev.ctx.embedding_view = {}; runtime_ev.ctx.embedding_view_bound = false; runtime_ev.ctx.embedding_row_ok = false; @@ -285,8 +284,9 @@ struct effect_bind_input_audio_embedding { void operator()(const event::step_run &runtime_ev, const context &ctx) const noexcept { const int32_t index = runtime_ev.ctx.input_audio_codebook_index; - const auto *audio_emb = detail::find_indexed_tensor( - runtime_ev.request.model, "lm.emb.%d.weight", index); + const auto *audio_emb = + ctx.session.contract.lm.audio_embeddings[static_cast(index)] + .tensor; runtime_ev.ctx.embedding_view = {}; runtime_ev.ctx.embedding_view_bound = false; runtime_ev.ctx.embedding_row_ok = false; diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 66ca04e7..0fada7dc 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -44,6 +44,36 @@ struct guard_bind_contract_invalid { } }; +struct guard_bound_input_embeddings_supported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t hidden_dim = ctx.session.hidden_dim; + const auto *text_emb = ctx.session.contract.lm.text_embedding.tensor; + bool supported = + detail::tensor_shape(text_emb, hidden_dim, lm.text_card + 1) && + detail::supported_get_rows_dtype( + static_cast(text_emb->type)); + for (int32_t index = 0; index < lm.n_q; ++index) { + const auto *audio_emb = + ctx.session.contract.lm.audio_embeddings[static_cast(index)] + .tensor; + supported = supported && + detail::tensor_shape(audio_emb, hidden_dim, lm.card + 1) && + detail::supported_get_rows_dtype( + static_cast(audio_emb->type)); + } + return supported; + } +}; + +struct guard_bound_input_embeddings_unsupported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_bound_input_embeddings_supported{}(runtime_ev, ctx); + } +}; + struct guard_sampling_seed_nonzero { bool operator()(const event::initialize_run &runtime_ev, const action::context &) const noexcept { @@ -138,24 +168,8 @@ struct guard_external_input_embedding_supported { struct guard_token_input_embedding_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t hidden_dim = ctx.session.hidden_dim; - const auto *text_emb = detail::find_tensor(model, "lm.text_emb.weight"); - const bool root_tensors_ok = - detail::tensor_shape(text_emb, hidden_dim, lm.text_card + 1) && - detail::supported_get_rows_dtype( - static_cast(text_emb->type)); - bool audio_tensors_ok = true; - for (int32_t index = 0; index < lm.n_q; ++index) { - const auto *audio_emb = - detail::find_indexed_tensor(model, "lm.emb.%d.weight", index); - audio_tensors_ok = - audio_tensors_ok && - detail::tensor_shape(audio_emb, hidden_dim, lm.card + 1) && - detail::supported_get_rows_dtype( - static_cast(audio_emb->type)); - } bool tokens_ok = runtime_ev.request.input_sequence[0] != ctx.policy.token_zero && detail::token_in_embedding_range(runtime_ev.request.input_sequence[0], @@ -170,7 +184,7 @@ struct guard_token_input_embedding_supported { return runtime_ev.request.input_embedding.data() == nullptr && !lm.demux_second_stream && hidden_dim > 0 && static_cast(hidden_dim) <= ctx.capacity.hidden_dim && - root_tensors_ok && audio_tensors_ok && tokens_ok; + tokens_ok; } }; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index eb82aa89..c0a79d29 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -13,6 +13,7 @@ namespace emel::speech::predictor::moshi::executor { struct state_uninitialized {}; struct state_bind_contract_decision {}; +struct state_input_embedding_contract_decision {}; struct state_sampling_seed_decision {}; struct state_text_sampling_top_k_decision {}; struct state_audio_sampling_top_k_decision {}; @@ -173,12 +174,22 @@ struct model { // Bind the Moshi LM execution contract. sml::state <= *sml::state + sml::event - , sml::state <= sml::state + , sml::state <= + sml::state + sml::completion [ guard::guard_bind_contract_valid{} ] / action::effect_bind_contract{} , sml::state <= sml::state + sml::completion [ guard::guard_bind_contract_invalid{} ] / action::effect_mark_bind_failed{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_bound_input_embeddings_supported{} ] + , sml::state <= + sml::state + + sml::completion + [ guard::guard_bound_input_embeddings_unsupported{} ] + / action::effect_mark_bind_failed{} , sml::state <= sml::state + sml::completion [ guard::guard_sampling_seed_nonzero{} ] / action::effect_bind_nonzero_sampling_seed{} diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index fb3ef23c..2803e610 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -476,6 +476,14 @@ TEST_CASE("enriched moshi lm fixture loads hparams, vocab, and contract") { REQUIRE(moshi::build_execution_contract(model, contract) == k_none); CHECK(contract.component == emel::model::data::moshi_component::lm); CHECK(contract.lm.audio_emb.tensor_count == 4u); + REQUIRE(contract.lm.text_embedding.tensor != nullptr); + CHECK(contract.lm.text_embedding.name == "lm.text_emb.weight"); + for (int32_t codebook = 0; codebook < model.moshi_lm.n_q; ++codebook) { + const auto &embedding = + contract.lm.audio_embeddings[static_cast(codebook)]; + REQUIRE(embedding.tensor != nullptr); + CHECK(embedding.name == "lm.emb." + std::to_string(codebook) + ".weight"); + } CHECK(contract.lm.transformer.tensor_count > 0u); CHECK(contract.lm.depformer.tensor_count > 0u); CHECK(contract.lm.linears.tensor_count == 4u); diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 77c4ac4a..9b520c8b 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -1494,11 +1494,21 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { executor_ctx.session.text_card = lm.text_card; executor_ctx.session.audio_card = lm.card; executor_ctx.session.hidden_dim = lm.dim; + REQUIRE(emel::model::moshi::detail::build_execution_contract( + *fixture.model, executor_ctx.session.contract) == k_no_error); moshi_executor::event::initialize executor_init{*fixture.model}; moshi_executor::event::initialize_ctx executor_init_ctx{}; moshi_executor::event::initialize_run executor_init_run{executor_init, executor_init_ctx}; + CHECK(moshi_executor::guard::guard_bound_input_embeddings_supported{}( + executor_init_run, executor_ctx)); + const auto *bound_text_embedding = + executor_ctx.session.contract.lm.text_embedding.tensor; + executor_ctx.session.contract.lm.text_embedding.tensor = nullptr; + CHECK(moshi_executor::guard::guard_bound_input_embeddings_unsupported{}( + executor_init_run, executor_ctx)); + executor_ctx.session.contract.lm.text_embedding.tensor = bound_text_embedding; executor_init.on_done = emel::callback:: from Date: Fri, 10 Jul 2026 23:20:56 -0500 Subject: [PATCH 30/61] perf: prebind moshi root projections --- .../speech_predictor_moshi_executor.mmd | 14 ++++----- .../speech_predictor_moshi_executor.md | 28 +++++++---------- src/emel/model/moshi/detail.cpp | 12 ++++++++ src/emel/model/moshi/detail.hpp | 2 ++ .../predictor/moshi/executor/actions.hpp | 8 ++--- .../predictor/moshi/executor/guards.hpp | 30 +++++++++---------- .../speech/predictor/moshi/executor/sm.hpp | 4 +-- tests/model/moshi/binding_tests.cpp | 4 +++ .../predictor/moshi_lifecycle_tests.cpp | 4 +-- 9 files changed, 56 insertions(+), 50 deletions(-) diff --git a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd index 193c6cc8..8cf3087e 100644 --- a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd +++ b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd @@ -2,8 +2,10 @@ stateDiagram-v2 direction TB [*] --> state_uninitialized state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none - state_bind_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ + state_bind_contract_decision --> state_input_embedding_contract_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ + state_input_embedding_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none + state_input_embedding_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bound_root_operands_unsupported_] / effect_mark_bind_failed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ @@ -150,11 +152,8 @@ stateDiagram-v2 state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid_] / effect_mark_graph_execution_unsupported_ state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ state_text_logits_sample_projection --> state_text_logits_sample_projection_result_decision : completion_step_run_ [always] / none - state_text_logits_sample_projection_result_decision --> state_text_logits_sample_scale : completion_step_run_ [guard_text_logits_matmul_succeeded_] / effect_scale_text_sampling_logits_ + state_text_logits_sample_projection_result_decision --> state_text_logits_sample_select : completion_step_run_ [guard_text_logits_matmul_succeeded_] / effect_select_text_sampling_token_ state_text_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ - state_text_logits_sample_scale --> state_text_logits_sample_softmax : completion_step_run_ [always] / effect_compute_text_sampling_probabilities_ - state_text_logits_sample_softmax --> state_text_logits_sample_top_k : completion_step_run_ [always] / effect_compute_text_sampling_top_k_ - state_text_logits_sample_top_k --> state_text_logits_sample_select : completion_step_run_ [always] / effect_select_text_sampling_token_ state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_sampled_text_token_ready_] / effect_publish_sampled_text_token_ state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_sampling_consumed_] / effect_publish_forced_text_token_ state_text_logits_sample_select --> state_step_error_out_decision : completion_step_run_ [guard_text_sampling_failed_] / effect_mark_graph_execution_unsupported_ @@ -263,11 +262,8 @@ stateDiagram-v2 state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_projection_bound_sampling_invalid_] / effect_mark_graph_execution_unsupported_ state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ state_depformer_logits_sample_projection --> state_depformer_logits_sample_projection_result_decision : completion_step_run_ [always] / none - state_depformer_logits_sample_projection_result_decision --> state_depformer_logits_sample_scale : completion_step_run_ [guard_depformer_logits_matmul_succeeded_] / effect_scale_depformer_sampling_logits_ + state_depformer_logits_sample_projection_result_decision --> state_depformer_logits_sample_select : completion_step_run_ [guard_depformer_logits_matmul_succeeded_] / effect_select_depformer_sampling_token_ state_depformer_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ - state_depformer_logits_sample_scale --> state_depformer_logits_sample_softmax : completion_step_run_ [always] / effect_compute_depformer_sampling_probabilities_ - state_depformer_logits_sample_softmax --> state_depformer_logits_sample_top_k : completion_step_run_ [always] / effect_compute_depformer_sampling_top_k_ - state_depformer_logits_sample_top_k --> state_depformer_logits_sample_select : completion_step_run_ [always] / effect_select_depformer_sampling_token_ state_depformer_layer_advance --> state_depformer_layer_norm : completion_step_run_ [guard_depformer_layer_norm_supported_] / effect_run_depformer_layer_norm_rms_ state_depformer_layer_advance --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ state_depformer_logits_run --> state_depformer_token_publish : completion_step_run_ [guard_depformer_logits_succeeded_] / effect_publish_depformer_token_ diff --git a/.planning/architecture/speech_predictor_moshi_executor.md b/.planning/architecture/speech_predictor_moshi_executor.md index fe38a8ef..b3d535a1 100644 --- a/.planning/architecture/speech_predictor_moshi_executor.md +++ b/.planning/architecture/speech_predictor_moshi_executor.md @@ -9,8 +9,10 @@ stateDiagram-v2 direction TB [*] --> state_uninitialized state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none - state_bind_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ + state_bind_contract_decision --> state_input_embedding_contract_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ + state_input_embedding_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none + state_input_embedding_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bound_root_operands_unsupported_] / effect_mark_bind_failed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ @@ -157,11 +159,8 @@ stateDiagram-v2 state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid_] / effect_mark_graph_execution_unsupported_ state_text_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ state_text_logits_sample_projection --> state_text_logits_sample_projection_result_decision : completion_step_run_ [always] / none - state_text_logits_sample_projection_result_decision --> state_text_logits_sample_scale : completion_step_run_ [guard_text_logits_matmul_succeeded_] / effect_scale_text_sampling_logits_ + state_text_logits_sample_projection_result_decision --> state_text_logits_sample_select : completion_step_run_ [guard_text_logits_matmul_succeeded_] / effect_select_text_sampling_token_ state_text_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ - state_text_logits_sample_scale --> state_text_logits_sample_softmax : completion_step_run_ [always] / effect_compute_text_sampling_probabilities_ - state_text_logits_sample_softmax --> state_text_logits_sample_top_k : completion_step_run_ [always] / effect_compute_text_sampling_top_k_ - state_text_logits_sample_top_k --> state_text_logits_sample_select : completion_step_run_ [always] / effect_select_text_sampling_token_ state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_sampled_text_token_ready_] / effect_publish_sampled_text_token_ state_text_logits_sample_select --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_sampling_consumed_] / effect_publish_forced_text_token_ state_text_logits_sample_select --> state_step_error_out_decision : completion_step_run_ [guard_text_sampling_failed_] / effect_mark_graph_execution_unsupported_ @@ -270,11 +269,8 @@ stateDiagram-v2 state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_projection_bound_sampling_invalid_] / effect_mark_graph_execution_unsupported_ state_depformer_logits_bind_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_projection_view_bind_failed_] / effect_mark_graph_execution_unsupported_ state_depformer_logits_sample_projection --> state_depformer_logits_sample_projection_result_decision : completion_step_run_ [always] / none - state_depformer_logits_sample_projection_result_decision --> state_depformer_logits_sample_scale : completion_step_run_ [guard_depformer_logits_matmul_succeeded_] / effect_scale_depformer_sampling_logits_ + state_depformer_logits_sample_projection_result_decision --> state_depformer_logits_sample_select : completion_step_run_ [guard_depformer_logits_matmul_succeeded_] / effect_select_depformer_sampling_token_ state_depformer_logits_sample_projection_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_depformer_logits_matmul_failed_] / effect_mark_graph_execution_unsupported_ - state_depformer_logits_sample_scale --> state_depformer_logits_sample_softmax : completion_step_run_ [always] / effect_compute_depformer_sampling_probabilities_ - state_depformer_logits_sample_softmax --> state_depformer_logits_sample_top_k : completion_step_run_ [always] / effect_compute_depformer_sampling_top_k_ - state_depformer_logits_sample_top_k --> state_depformer_logits_sample_select : completion_step_run_ [always] / effect_select_depformer_sampling_token_ state_depformer_layer_advance --> state_depformer_layer_norm : completion_step_run_ [guard_depformer_layer_norm_supported_] / effect_run_depformer_layer_norm_rms_ state_depformer_layer_advance --> state_step_error_out_decision : completion_step_run_ [guard_depformer_layer_norm_unsupported_] / effect_mark_graph_execution_unsupported_ state_depformer_logits_run --> state_depformer_token_publish : completion_step_run_ [guard_depformer_logits_succeeded_] / effect_publish_depformer_token_ @@ -300,8 +296,10 @@ stateDiagram-v2 | Source | Event | Guard | Action | Target | | --- | --- | --- | --- | --- | | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bound_root_operands_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bound_root_operands_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_nonzero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_nonzero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_zero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_requested_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | @@ -448,11 +446,8 @@ stateDiagram-v2 | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_projection_bound_and_no_forced_token_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_scale_text_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_text_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_text_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_text_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampled_text_token_ready>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_sampled_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_forced_text_sampling_consumed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_sampling_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | @@ -561,11 +556,8 @@ stateDiagram-v2 | [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_projection_bound_sampling_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_depformer_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_projection_view_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_depformer_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_scale_depformer_sampling_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_depformer_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_depformer_logits_sample_projection_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_matmul_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_softmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_depformer_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_depformer_logits_sample_top_k`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_select_depformer_sampling_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_logits_sample_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_run_depformer_layer_norm_rms>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_layer_norm`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_depformer_layer_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_layer_norm_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_depformer_logits_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_logits_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_depformer_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_token_publish`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index 2c373dc5..769ef54e 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -652,6 +652,18 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, .tensor = text_embedding, .name = emel::model::tensor_name_view(model_data, *text_embedding), }; + const auto *output_norm = find_tensor(model_data, "lm.out_norm.alpha"); + contract_out.output_norm = tensor_view{ + .tensor = output_norm, + .name = emel::model::tensor_name_view(model_data, *output_norm), + }; + const auto *text_output_projection = + find_tensor(model_data, "lm.text_linear.weight"); + contract_out.text_output_projection = tensor_view{ + .tensor = text_output_projection, + .name = + emel::model::tensor_name_view(model_data, *text_output_projection), + }; for (int32_t codebook = 0; codebook < lm.n_q; ++codebook) { char name[96] = {}; const int written = diff --git a/src/emel/model/moshi/detail.hpp b/src/emel/model/moshi/detail.hpp index f87e301c..bc5a606a 100644 --- a/src/emel/model/moshi/detail.hpp +++ b/src/emel/model/moshi/detail.hpp @@ -48,6 +48,8 @@ struct lm_contract { family_view depformer_text_emb = {}; family_view depformer_emb = {}; tensor_view text_embedding = {}; + tensor_view output_norm = {}; + tensor_view text_output_projection = {}; std::array( emel::model::data::moshi_lm_hparams::k_max_delays)> diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 08c83dbf..d352a711 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -898,8 +898,7 @@ struct effect_run_temporal_out_norm_scale { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { const int32_t hidden_dim = ctx.session.hidden_dim; - const auto *out_norm = - detail::find_tensor(runtime_ev.request.model, "lm.out_norm.alpha"); + const auto *out_norm = ctx.session.contract.lm.output_norm.tensor; const auto *alpha = static_cast(out_norm->data); runtime_ev.ctx.temporal_out_norm_ok = false; @@ -925,9 +924,10 @@ struct effect_publish_temporal_out_norm { }; struct effect_bind_text_token_logits { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { const auto *text_linear = - detail::find_tensor(runtime_ev.request.model, "lm.text_linear.weight"); + ctx.session.contract.lm.text_output_projection.tensor; runtime_ev.ctx.text_logits_ok = false; runtime_ev.ctx.projection_view_bound = false; runtime_ev.ctx.projection_view = {}; diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 0fada7dc..521c64c7 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -44,16 +44,25 @@ struct guard_bind_contract_invalid { } }; -struct guard_bound_input_embeddings_supported { +struct guard_bound_root_operands_supported { bool operator()(const event::initialize_run &runtime_ev, const action::context &ctx) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t hidden_dim = ctx.session.hidden_dim; const auto *text_emb = ctx.session.contract.lm.text_embedding.tensor; + const auto *output_norm = ctx.session.contract.lm.output_norm.tensor; + const auto *text_output_projection = + ctx.session.contract.lm.text_output_projection.tensor; bool supported = detail::tensor_shape(text_emb, hidden_dim, lm.text_card + 1) && detail::supported_get_rows_dtype( - static_cast(text_emb->type)); + static_cast(text_emb->type)) && + detail::tensor_shape(output_norm, hidden_dim) && + static_cast(output_norm->type) == detail::dtype::f32 && + detail::tensor_shape(text_output_projection, hidden_dim, + lm.text_card) && + detail::supported_argmax_dtype( + static_cast(text_output_projection->type)); for (int32_t index = 0; index < lm.n_q; ++index) { const auto *audio_emb = ctx.session.contract.lm.audio_embeddings[static_cast(index)] @@ -67,10 +76,10 @@ struct guard_bound_input_embeddings_supported { } }; -struct guard_bound_input_embeddings_unsupported { +struct guard_bound_root_operands_unsupported { bool operator()(const event::initialize_run &runtime_ev, const action::context &ctx) const noexcept { - return !guard_bound_input_embeddings_supported{}(runtime_ev, ctx); + return !guard_bound_root_operands_supported{}(runtime_ev, ctx); } }; @@ -920,13 +929,9 @@ struct guard_temporal_out_norm_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { const int32_t hidden_dim = ctx.session.hidden_dim; - const auto *out_norm = - detail::find_tensor(runtime_ev.request.model, "lm.out_norm.alpha"); return guard_temporal_layers_complete{}(runtime_ev, ctx) && hidden_dim > 0 && - static_cast(hidden_dim) <= ctx.capacity.hidden_dim && - detail::tensor_shape(out_norm, hidden_dim) && - static_cast(out_norm->type) == detail::dtype::f32; + static_cast(hidden_dim) <= ctx.capacity.hidden_dim; } }; @@ -970,13 +975,8 @@ struct guard_text_logits_supported { const action::context &ctx) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t hidden_dim = ctx.session.hidden_dim; - const auto *text_linear = - detail::find_tensor(runtime_ev.request.model, "lm.text_linear.weight"); return runtime_ev.ctx.temporal_out_norm_ok && hidden_dim > 0 && - lm.text_card > 0 && - detail::tensor_shape(text_linear, hidden_dim, lm.text_card) && - detail::supported_argmax_dtype( - static_cast(text_linear->type)); + lm.text_card > 0; } }; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index c0a79d29..8b7bb1ed 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -184,11 +184,11 @@ struct model { , sml::state <= sml::state + sml::completion - [ guard::guard_bound_input_embeddings_supported{} ] + [ guard::guard_bound_root_operands_supported{} ] , sml::state <= sml::state + sml::completion - [ guard::guard_bound_input_embeddings_unsupported{} ] + [ guard::guard_bound_root_operands_unsupported{} ] / action::effect_mark_bind_failed{} , sml::state <= sml::state + sml::completion [ guard::guard_sampling_seed_nonzero{} ] diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index 2803e610..69f58d27 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -478,6 +478,10 @@ TEST_CASE("enriched moshi lm fixture loads hparams, vocab, and contract") { CHECK(contract.lm.audio_emb.tensor_count == 4u); REQUIRE(contract.lm.text_embedding.tensor != nullptr); CHECK(contract.lm.text_embedding.name == "lm.text_emb.weight"); + REQUIRE(contract.lm.output_norm.tensor != nullptr); + CHECK(contract.lm.output_norm.name == "lm.out_norm.alpha"); + REQUIRE(contract.lm.text_output_projection.tensor != nullptr); + CHECK(contract.lm.text_output_projection.name == "lm.text_linear.weight"); for (int32_t codebook = 0; codebook < model.moshi_lm.n_q; ++codebook) { const auto &embedding = contract.lm.audio_embeddings[static_cast(codebook)]; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 9b520c8b..3c7983f9 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -1501,12 +1501,12 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { moshi_executor::event::initialize_ctx executor_init_ctx{}; moshi_executor::event::initialize_run executor_init_run{executor_init, executor_init_ctx}; - CHECK(moshi_executor::guard::guard_bound_input_embeddings_supported{}( + CHECK(moshi_executor::guard::guard_bound_root_operands_supported{}( executor_init_run, executor_ctx)); const auto *bound_text_embedding = executor_ctx.session.contract.lm.text_embedding.tensor; executor_ctx.session.contract.lm.text_embedding.tensor = nullptr; - CHECK(moshi_executor::guard::guard_bound_input_embeddings_unsupported{}( + CHECK(moshi_executor::guard::guard_bound_root_operands_unsupported{}( executor_init_run, executor_ctx)); executor_ctx.session.contract.lm.text_embedding.tensor = bound_text_embedding; executor_init.on_done = From 1eae04f2c3da3ad8ec9b4212d52e5d15bc2c2c20 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 23:30:25 -0500 Subject: [PATCH 31/61] perf: prebind moshi depformer roots --- src/emel/model/moshi/detail.cpp | 65 +++++++++++++++++ src/emel/model/moshi/detail.hpp | 13 ++++ .../predictor/moshi/executor/actions.hpp | 43 +++++++----- .../predictor/moshi/executor/guards.hpp | 69 +++++++++++-------- tests/model/moshi/binding_tests.cpp | 23 +++++++ 5 files changed, 164 insertions(+), 49 deletions(-) diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index 769ef54e..b72800e2 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -708,6 +708,71 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, return emel::error::cast(emel::model::loader::error::model_invalid); } + const auto *depformer_text_embedding = + find_tensor(model_data, "lm.depformer_text_emb.weight"); + if (depformer_text_embedding == nullptr) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + contract_out.depformer_text_embedding = tensor_view{ + .tensor = depformer_text_embedding, + .name = emel::model::tensor_name_view(model_data, + *depformer_text_embedding), + }; + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + char name[96] = {}; + int written = std::snprintf(name, sizeof(name), + "lm.depformer_in.%d.weight", codebook); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + const auto *input_projection = find_tensor( + model_data, std::string_view{name, static_cast(written)}); + if (input_projection == nullptr) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + contract_out.depformer_input_projections[static_cast(codebook)] = + tensor_view{ + .tensor = input_projection, + .name = + emel::model::tensor_name_view(model_data, *input_projection), + }; + + written = + std::snprintf(name, sizeof(name), "lm.linears.%d.weight", codebook); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + const auto *output_projection = find_tensor( + model_data, std::string_view{name, static_cast(written)}); + if (output_projection == nullptr) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + contract_out.depformer_output_projections[static_cast(codebook)] = + tensor_view{ + .tensor = output_projection, + .name = + emel::model::tensor_name_view(model_data, *output_projection), + }; + + if (codebook > 0) { + written = std::snprintf(name, sizeof(name), + "lm.depformer_emb.%d.weight", codebook - 1); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + const auto *audio_embedding = find_tensor( + model_data, std::string_view{name, static_cast(written)}); + if (audio_embedding == nullptr) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + contract_out.depformer_audio_embeddings[static_cast( + codebook - 1)] = tensor_view{ + .tensor = audio_embedding, + .name = emel::model::tensor_name_view(model_data, *audio_embedding), + }; + } + } + for (int32_t block = 0; block < lm.depformer_num_layers; ++block) { if (!has_depformer_block(model_data, block)) { return emel::error::cast(emel::model::loader::error::model_invalid); diff --git a/src/emel/model/moshi/detail.hpp b/src/emel/model/moshi/detail.hpp index bc5a606a..84aea382 100644 --- a/src/emel/model/moshi/detail.hpp +++ b/src/emel/model/moshi/detail.hpp @@ -50,10 +50,23 @@ struct lm_contract { tensor_view text_embedding = {}; tensor_view output_norm = {}; tensor_view text_output_projection = {}; + tensor_view depformer_text_embedding = {}; std::array( emel::model::data::moshi_lm_hparams::k_max_delays)> audio_embeddings = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + depformer_input_projections = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + depformer_audio_embeddings = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + depformer_output_projections = {}; }; struct mimi_contract { diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index d352a711..025c5b38 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -1041,9 +1041,7 @@ struct effect_advance_depformer_position { struct effect_bind_depformer_text_input_projection { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; - (void)ctx; + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; runtime_ev.ctx.depformer_input_ok = false; runtime_ev.ctx.depformer_input_projection_bound = false; @@ -1080,8 +1078,10 @@ struct effect_bind_depformer_text_input_projection { 0.0f); const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; - const auto *input_projection = detail::find_indexed_tensor( - model, "lm.depformer_in.%d.weight", weight_index); + const auto *input_projection = + ctx.session.contract.lm + .depformer_input_projections[static_cast(weight_index)] + .tensor; runtime_ev.ctx.projection_view = {}; runtime_ev.ctx.depformer_input_projection_bound = detail::bind_tensor_view( *input_projection, runtime_ev.ctx.projection_view); @@ -1091,9 +1091,7 @@ struct effect_bind_depformer_text_input_projection { struct effect_bind_depformer_audio_input_projection { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; - (void)ctx; + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; runtime_ev.ctx.depformer_input_ok = false; @@ -1130,8 +1128,10 @@ struct effect_bind_depformer_audio_input_projection { std::fill_n(runtime_ev.ctx.attention.data(), static_cast(dep_dim), 0.0f); - const auto *input_projection = detail::find_indexed_tensor( - model, "lm.depformer_in.%d.weight", weight_index); + const auto *input_projection = + ctx.session.contract.lm + .depformer_input_projections[static_cast(weight_index)] + .tensor; runtime_ev.ctx.projection_view = {}; runtime_ev.ctx.depformer_input_projection_bound = detail::bind_tensor_view( *input_projection, runtime_ev.ctx.projection_view); @@ -1159,10 +1159,10 @@ struct effect_run_depformer_input_projection { struct effect_bind_depformer_text_input_embedding { void operator()(const event::step_run &runtime_ev, - const context &) const noexcept { + const context &ctx) const noexcept { const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; - const auto *text_emb = detail::find_tensor(runtime_ev.request.model, - "lm.depformer_text_emb.weight"); + const auto *text_emb = + ctx.session.contract.lm.depformer_text_embedding.tensor; runtime_ev.ctx.embedding_view = {}; runtime_ev.ctx.embedding_view_bound = false; runtime_ev.ctx.embedding_row_ok = false; @@ -1176,12 +1176,14 @@ struct effect_bind_depformer_text_input_embedding { struct effect_bind_depformer_audio_input_embedding { void operator()(const event::step_run &runtime_ev, - const context &) const noexcept { + const context &ctx) const noexcept { const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; - const auto *audio_emb = detail::find_indexed_tensor( - runtime_ev.request.model, "lm.depformer_emb.%d.weight", codebook - 1); + const auto *audio_emb = + ctx.session.contract.lm + .depformer_audio_embeddings[static_cast(codebook - 1)] + .tensor; runtime_ev.ctx.embedding_view = {}; runtime_ev.ctx.embedding_view_bound = false; runtime_ev.ctx.embedding_row_ok = false; @@ -1670,10 +1672,13 @@ struct effect_advance_depformer_layer { }; struct effect_bind_depformer_token_logits { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; - const auto *linear = detail::find_indexed_tensor( - runtime_ev.request.model, "lm.linears.%d.weight", codebook); + const auto *linear = + ctx.session.contract.lm + .depformer_output_projections[static_cast(codebook)] + .tensor; runtime_ev.ctx.depformer_logits_ok = false; runtime_ev.ctx.projection_view_bound = false; runtime_ev.ctx.projection_view = {}; diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 521c64c7..6a1e4dbc 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -72,6 +72,42 @@ struct guard_bound_root_operands_supported { detail::supported_get_rows_dtype( static_cast(audio_emb->type)); } + const int32_t dep_dim = lm.depformer_dim; + const auto *depformer_text_embedding = + ctx.session.contract.lm.depformer_text_embedding.tensor; + supported = supported && dep_dim > 0 && + detail::tensor_shape(depformer_text_embedding, dep_dim, + lm.text_card + 1) && + detail::supported_get_rows_dtype( + static_cast(depformer_text_embedding->type)); + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + const auto *input_projection = + ctx.session.contract.lm + .depformer_input_projections[static_cast(codebook)] + .tensor; + const auto *output_projection = + ctx.session.contract.lm + .depformer_output_projections[static_cast(codebook)] + .tensor; + supported = supported && + detail::tensor_shape(input_projection, hidden_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(input_projection->type)) && + detail::tensor_shape(output_projection, dep_dim, lm.card) && + detail::supported_argmax_dtype( + static_cast(output_projection->type)); + if (codebook > 0) { + const auto *audio_embedding = + ctx.session.contract.lm + .depformer_audio_embeddings[static_cast(codebook - 1)] + .tensor; + supported = + supported && + detail::tensor_shape(audio_embedding, dep_dim, lm.card + 1) && + detail::supported_get_rows_dtype( + static_cast(audio_embedding->type)); + } + } return supported; } }; @@ -1261,8 +1297,7 @@ struct guard_depformer_scheduled_weight_invalid { struct guard_depformer_text_input_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; if (codebook != 0) { return false; @@ -1273,19 +1308,9 @@ struct guard_depformer_text_input_supported { if (weight_index < 0 || weight_index >= lm.dep_q) { return false; } - const auto *input_projection = detail::find_indexed_tensor( - model, "lm.depformer_in.%d.weight", weight_index); - const auto *embedding = - detail::find_tensor(model, "lm.depformer_text_emb.weight"); return runtime_ev.ctx.depformer_kv_bound && runtime_ev.ctx.text_logits_ok && codebook == 0 && hidden_dim > 0 && dep_dim > 0 && static_cast(dep_dim) <= ctx.capacity.hidden_dim && - detail::tensor_shape(input_projection, hidden_dim, dep_dim) && - detail::supported_mul_mat_dtype( - static_cast(input_projection->type)) && - detail::tensor_shape(embedding, dep_dim, lm.text_card + 1) && - detail::supported_get_rows_dtype( - static_cast(embedding->type)) && detail::token_in_embedding_range(runtime_ev.request.text_token_out, lm.text_card, ctx.policy.token_zero); @@ -1295,8 +1320,7 @@ struct guard_depformer_text_input_supported { struct guard_depformer_audio_input_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; if (codebook <= 0 || codebook >= lm.dep_q) { return false; @@ -1307,20 +1331,10 @@ struct guard_depformer_audio_input_supported { if (weight_index < 0 || weight_index >= lm.dep_q) { return false; } - const auto *input_projection = detail::find_indexed_tensor( - model, "lm.depformer_in.%d.weight", weight_index); - const auto *embedding = detail::find_indexed_tensor( - model, "lm.depformer_emb.%d.weight", codebook - 1); return runtime_ev.ctx.depformer_kv_bound && runtime_ev.ctx.text_logits_ok && codebook > 0 && codebook < lm.dep_q && hidden_dim > 0 && dep_dim > 0 && static_cast(dep_dim) <= ctx.capacity.hidden_dim && - detail::tensor_shape(input_projection, hidden_dim, dep_dim) && - detail::supported_mul_mat_dtype( - static_cast(input_projection->type)) && - detail::tensor_shape(embedding, dep_dim, lm.card + 1) && - detail::supported_get_rows_dtype( - static_cast(embedding->type)) && detail::token_in_embedding_range( runtime_ev.request .audio_tokens_out[static_cast(codebook - 1)], @@ -1920,13 +1934,8 @@ struct guard_depformer_logits_supported { const auto &lm = model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; - const auto *linear = - detail::find_indexed_tensor(model, "lm.linears.%d.weight", codebook); return guard_depformer_layers_complete{}(runtime_ev, ctx) && - codebook >= 0 && codebook < lm.dep_q && dep_dim > 0 && lm.card > 0 && - detail::tensor_shape(linear, dep_dim, lm.card) && - detail::supported_argmax_dtype( - static_cast(linear->type)); + codebook >= 0 && codebook < lm.dep_q && dep_dim > 0 && lm.card > 0; } }; diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index 69f58d27..227af044 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -488,6 +488,29 @@ TEST_CASE("enriched moshi lm fixture loads hparams, vocab, and contract") { REQUIRE(embedding.tensor != nullptr); CHECK(embedding.name == "lm.emb." + std::to_string(codebook) + ".weight"); } + REQUIRE(contract.lm.depformer_text_embedding.tensor != nullptr); + CHECK(contract.lm.depformer_text_embedding.name == + "lm.depformer_text_emb.weight"); + for (int32_t codebook = 0; codebook < model.moshi_lm.dep_q; ++codebook) { + const auto &input_projection = + contract.lm.depformer_input_projections[static_cast(codebook)]; + REQUIRE(input_projection.tensor != nullptr); + CHECK(input_projection.name == + "lm.depformer_in." + std::to_string(codebook) + ".weight"); + const auto &output_projection = + contract.lm.depformer_output_projections[static_cast(codebook)]; + REQUIRE(output_projection.tensor != nullptr); + CHECK(output_projection.name == + "lm.linears." + std::to_string(codebook) + ".weight"); + if (codebook > 0) { + const auto &audio_embedding = + contract.lm + .depformer_audio_embeddings[static_cast(codebook - 1)]; + REQUIRE(audio_embedding.tensor != nullptr); + CHECK(audio_embedding.name == + "lm.depformer_emb." + std::to_string(codebook - 1) + ".weight"); + } + } CHECK(contract.lm.transformer.tensor_count > 0u); CHECK(contract.lm.depformer.tensor_count > 0u); CHECK(contract.lm.linears.tensor_count == 4u); From 49c8364e84750cd2e0ea149e378059ddcbef5602 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Fri, 10 Jul 2026 23:43:00 -0500 Subject: [PATCH 32/61] perf: prebind moshi temporal layers --- .../speech_predictor_moshi_executor.mmd | 5 +- .../speech_predictor_moshi_executor.md | 10 +- src/emel/model/moshi/detail.cpp | 80 +++++++++ src/emel/model/moshi/detail.hpp | 14 ++ .../predictor/moshi/executor/actions.hpp | 81 +++++---- .../predictor/moshi/executor/context.hpp | 5 + .../predictor/moshi/executor/guards.hpp | 165 +++++++++++------- .../speech/predictor/moshi/executor/sm.hpp | 18 +- tests/model/moshi/binding_tests.cpp | 12 ++ .../predictor/moshi_lifecycle_tests.cpp | 31 ++++ 10 files changed, 321 insertions(+), 100 deletions(-) diff --git a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd index 8cf3087e..c67a35b6 100644 --- a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd +++ b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd @@ -4,8 +4,11 @@ stateDiagram-v2 state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none state_bind_contract_decision --> state_input_embedding_contract_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ - state_input_embedding_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none + state_input_embedding_contract_decision --> state_temporal_projection_layout_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none state_input_embedding_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bound_root_operands_unsupported_] / effect_mark_bind_failed_ + state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_split_projection_layout_supported_] / effect_bind_temporal_split_projection_layout_ + state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_fused_projection_layout_supported_] / effect_bind_temporal_fused_projection_layout_ + state_temporal_projection_layout_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_temporal_projection_layout_unsupported_] / effect_mark_bind_failed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ diff --git a/.planning/architecture/speech_predictor_moshi_executor.md b/.planning/architecture/speech_predictor_moshi_executor.md index b3d535a1..ec109204 100644 --- a/.planning/architecture/speech_predictor_moshi_executor.md +++ b/.planning/architecture/speech_predictor_moshi_executor.md @@ -11,8 +11,11 @@ stateDiagram-v2 state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none state_bind_contract_decision --> state_input_embedding_contract_decision : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ - state_input_embedding_contract_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none + state_input_embedding_contract_decision --> state_temporal_projection_layout_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none state_input_embedding_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bound_root_operands_unsupported_] / effect_mark_bind_failed_ + state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_split_projection_layout_supported_] / effect_bind_temporal_split_projection_layout_ + state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_fused_projection_layout_supported_] / effect_bind_temporal_fused_projection_layout_ + state_temporal_projection_layout_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_temporal_projection_layout_unsupported_] / effect_mark_bind_failed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ @@ -298,8 +301,11 @@ stateDiagram-v2 | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bound_root_operands_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bound_root_operands_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bound_root_operands_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_split_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_split_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_fused_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_fused_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_projection_layout_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_nonzero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_nonzero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_zero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_requested_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index b72800e2..99847b69 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -464,6 +464,20 @@ find_tensor(const emel::model::data &model_data, return nullptr; } +bool bind_exact_tensor(const emel::model::data &model_data, + const std::string_view name, + tensor_view &view_out) noexcept { + const auto *tensor = find_tensor(model_data, name); + if (tensor == nullptr) { + return false; + } + view_out = tensor_view{ + .tensor = tensor, + .name = emel::model::tensor_name_view(model_data, *tensor), + }; + return true; +} + bool has_tensor(const emel::model::data &model_data, const std::string_view name) noexcept { const auto *tensor = find_tensor(model_data, name); @@ -682,10 +696,76 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, }; } + if (lm.num_layers > emel::model::data::moshi_lm_hparams::k_max_delays) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } for (int32_t block = 0; block < lm.num_layers; ++block) { if (!has_lm_transformer_block(model_data, block)) { return emel::error::cast(emel::model::loader::error::model_invalid); } + auto &layer = contract_out.temporal_layers[static_cast(block)]; + char name[128] = {}; + int written = std::snprintf(name, sizeof(name), + "lm.transformer.layers.%d.norm1.alpha", block); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor(model_data, + std::string_view{name, static_cast(written)}, + layer.norm1)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + written = std::snprintf( + name, sizeof(name), + "lm.transformer.layers.%d.self_attn.in_projs.0.weight", block); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + (void)bind_exact_tensor( + model_data, std::string_view{name, static_cast(written)}, + layer.split_input_projection); + written = std::snprintf(name, sizeof(name), + "lm.transformer.layers.%d.self_attn.in_proj_weight", + block); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + (void)bind_exact_tensor( + model_data, std::string_view{name, static_cast(written)}, + layer.fused_input_projection); + written = std::snprintf( + name, sizeof(name), + "lm.transformer.layers.%d.self_attn.out_projs.0.weight", block); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor(model_data, + std::string_view{name, static_cast(written)}, + layer.output_projection)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + written = std::snprintf(name, sizeof(name), + "lm.transformer.layers.%d.norm2.alpha", block); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor(model_data, + std::string_view{name, static_cast(written)}, + layer.norm2)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + written = std::snprintf(name, sizeof(name), + "lm.transformer.layers.%d.gating.linear_in.weight", + block); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor(model_data, + std::string_view{name, static_cast(written)}, + layer.gating_input)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + written = std::snprintf(name, sizeof(name), + "lm.transformer.layers.%d.gating.linear_out.weight", + block); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor(model_data, + std::string_view{name, static_cast(written)}, + layer.gating_output)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } } if (lm.dep_q > 0) { diff --git a/src/emel/model/moshi/detail.hpp b/src/emel/model/moshi/detail.hpp index 84aea382..e4d98c01 100644 --- a/src/emel/model/moshi/detail.hpp +++ b/src/emel/model/moshi/detail.hpp @@ -36,6 +36,16 @@ struct family_view { tensor_view first = {}; }; +struct temporal_layer_contract { + tensor_view norm1 = {}; + tensor_view split_input_projection = {}; + tensor_view fused_input_projection = {}; + tensor_view output_projection = {}; + tensor_view norm2 = {}; + tensor_view gating_input = {}; + tensor_view gating_output = {}; +}; + struct lm_contract { family_view text_emb = {}; family_view audio_emb = {}; @@ -67,6 +77,10 @@ struct lm_contract { static_cast( emel::model::data::moshi_lm_hparams::k_max_delays)> depformer_output_projections = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + temporal_layers = {}; }; struct mimi_contract { diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 025c5b38..f6974789 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -43,6 +43,28 @@ struct effect_bind_contract { } }; +struct effect_bind_temporal_split_projection_layout { + void operator()(const event::initialize_run &, context &ctx) const noexcept { + for (int32_t layer = 0; layer < ctx.session.model->moshi_lm.num_layers; + ++layer) { + ctx.session.temporal_input_projections[static_cast(layer)] = + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .split_input_projection.tensor; + } + } +}; + +struct effect_bind_temporal_fused_projection_layout { + void operator()(const event::initialize_run &, context &ctx) const noexcept { + for (int32_t layer = 0; layer < ctx.session.model->moshi_lm.num_layers; + ++layer) { + ctx.session.temporal_input_projections[static_cast(layer)] = + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .fused_input_projection.tensor; + } + } +}; + struct effect_bind_nonzero_sampling_seed { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { @@ -362,13 +384,13 @@ struct effect_run_temporal_layer_norm_rms { struct effect_run_temporal_layer_norm_scale { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; runtime_ev.ctx.temporal_layer_norm_ok = false; const auto *norm1 = - detail::find_lm_transformer_tensor(model, layer, "norm1.alpha"); + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .norm1.tensor; const auto *alpha = static_cast(norm1->data); emel::kernel::event::op_mul mul_ev{ @@ -385,7 +407,6 @@ struct effect_run_temporal_layer_norm_scale { struct effect_bind_temporal_layer_projection { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; runtime_ev.ctx.temporal_layer_projection_ok = false; @@ -395,7 +416,7 @@ struct effect_bind_temporal_layer_projection { 0.0f); const auto *projection = - detail::find_lm_transformer_projection(model, layer); + ctx.session.temporal_input_projections[static_cast(layer)]; runtime_ev.ctx.projection_view_bound = detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); } @@ -607,7 +628,6 @@ struct effect_run_temporal_layer_attention { struct effect_bind_temporal_layer_out_projection { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; runtime_ev.ctx.temporal_layer_out_projection_ok = false; @@ -616,8 +636,9 @@ struct effect_bind_temporal_layer_out_projection { std::fill_n(runtime_ev.ctx.projection.data(), static_cast(hidden_dim), 0.0f); - const auto *projection = detail::find_lm_transformer_tensor( - model, layer, "self_attn.out_projs.0.weight"); + const auto *projection = + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .output_projection.tensor; runtime_ev.ctx.projection_view_bound = detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); } @@ -680,13 +701,13 @@ struct effect_run_temporal_layer_norm2_rms { struct effect_run_temporal_layer_norm2_scale { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; runtime_ev.ctx.temporal_layer_norm2_ok = false; const auto *norm2 = - detail::find_lm_transformer_tensor(model, layer, "norm2.alpha"); + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .norm2.tensor; const auto *alpha = static_cast(norm2->data); emel::kernel::event::op_mul mul_ev{ @@ -703,11 +724,10 @@ struct effect_run_temporal_layer_norm2_scale { struct effect_bind_temporal_layer_gating_in { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - (void)ctx; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *linear_in = detail::find_lm_transformer_tensor( - model, layer, "gating.linear_in.weight"); + const auto *linear_in = + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); runtime_ev.ctx.temporal_layer_gating_in_ok = false; runtime_ev.ctx.projection_view_bound = false; @@ -723,11 +743,11 @@ struct effect_bind_temporal_layer_gating_in { struct effect_run_temporal_layer_gating_in { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *linear_in = detail::find_lm_transformer_tensor( - model, layer, "gating.linear_in.weight"); + const auto *linear_in = + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); runtime_ev.ctx.temporal_layer_gating_in_ok = false; emel::kernel::event::op_mul_mat projection_ev{ @@ -745,9 +765,10 @@ struct effect_run_temporal_layer_gating_in { struct effect_run_temporal_layer_silu_gate_silu { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto *linear_in = detail::find_lm_transformer_tensor( - runtime_ev.request.model, runtime_ev.ctx.temporal_layer_index, - "gating.linear_in.weight"); + const auto *linear_in = ctx.session.contract.lm + .temporal_layers[static_cast( + runtime_ev.ctx.temporal_layer_index)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); const uint64_t gate_dim = projection_dim / 2u; runtime_ev.ctx.temporal_layer_silu_gate_silu_ok = false; @@ -772,9 +793,10 @@ struct effect_run_temporal_layer_silu_gate_silu { struct effect_run_temporal_layer_silu_gate_mul { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto *linear_in = detail::find_lm_transformer_tensor( - runtime_ev.request.model, runtime_ev.ctx.temporal_layer_index, - "gating.linear_in.weight"); + const auto *linear_in = ctx.session.contract.lm + .temporal_layers[static_cast( + runtime_ev.ctx.temporal_layer_index)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); const uint64_t gate_dim = projection_dim / 2u; const float *right = runtime_ev.ctx.gating_projection.data() + gate_dim; @@ -794,13 +816,12 @@ struct effect_run_temporal_layer_silu_gate_mul { struct effect_bind_temporal_layer_gating_out { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *linear_in = detail::find_lm_transformer_tensor( - model, layer, "gating.linear_in.weight"); - const auto *linear_out = detail::find_lm_transformer_tensor( - model, layer, "gating.linear_out.weight"); + const auto &layer_contract = + ctx.session.contract.lm.temporal_layers[static_cast(layer)]; + const auto *linear_in = layer_contract.gating_input.tensor; + const auto *linear_out = layer_contract.gating_output.tensor; const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; (void)gate_dim; runtime_ev.ctx.temporal_layer_gating_out_ok = false; @@ -817,11 +838,11 @@ struct effect_bind_temporal_layer_gating_out { struct effect_run_temporal_layer_gating_out { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *linear_in = detail::find_lm_transformer_tensor( - model, layer, "gating.linear_in.weight"); + const auto *linear_in = + ctx.session.contract.lm.temporal_layers[static_cast(layer)] + .gating_input.tensor; const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; runtime_ev.ctx.temporal_layer_gating_out_ok = false; emel::kernel::event::op_mul_mat projection_ev{ diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index d6d69f05..f884be3d 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "emel/kernel/sm.hpp" @@ -49,6 +50,10 @@ struct runtime { int32_t text_card = 0; int32_t audio_card = 0; int32_t hidden_dim = 0; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + temporal_input_projections = {}; }; struct sampling_config { diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 6a1e4dbc..f5665211 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -108,6 +108,41 @@ struct guard_bound_root_operands_supported { static_cast(audio_embedding->type)); } } + for (int32_t layer_index = 0; layer_index < lm.num_layers; ++layer_index) { + const auto &layer = + ctx.session.contract.lm + .temporal_layers[static_cast(layer_index)]; + const auto *norm1 = layer.norm1.tensor; + const auto *output_projection = layer.output_projection.tensor; + const auto *norm2 = layer.norm2.tensor; + const auto *gating_input = layer.gating_input.tensor; + const auto *gating_output = layer.gating_output.tensor; + int64_t gating_projection_dim = 0; + if (gating_input != nullptr && gating_input->n_dims > 1) { + gating_projection_dim = gating_input->dims[1]; + } + const int64_t gating_dim = gating_projection_dim / 2; + supported = + supported && detail::tensor_shape(norm1, hidden_dim) && + static_cast(norm1->type) == detail::dtype::f32 && + detail::tensor_shape(output_projection, hidden_dim, hidden_dim) && + detail::supported_mul_mat_dtype( + static_cast(output_projection->type)) && + detail::tensor_shape(norm2, hidden_dim) && + static_cast(norm2->type) == detail::dtype::f32 && + gating_projection_dim > 0 && (gating_projection_dim % 2) == 0 && + static_cast(gating_projection_dim) <= + ctx.capacity.hidden_dim * 8u && + detail::tensor_shape(gating_input, hidden_dim, + gating_projection_dim) && + detail::supported_mul_mat_dtype( + static_cast(gating_input->type)) && + gating_dim > 0 && + static_cast(gating_dim) <= ctx.capacity.hidden_dim * 4u && + detail::tensor_shape(gating_output, gating_dim, hidden_dim) && + detail::supported_mul_mat_dtype( + static_cast(gating_output->type)); + } return supported; } }; @@ -119,6 +154,56 @@ struct guard_bound_root_operands_unsupported { } }; +struct guard_temporal_split_projection_layout_supported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + bool supported = lm.num_layers > 0; + for (int32_t layer_index = 0; layer_index < lm.num_layers; ++layer_index) { + const auto *projection = + ctx.session.contract.lm + .temporal_layers[static_cast(layer_index)] + .split_input_projection.tensor; + supported = supported && + detail::tensor_shape(projection, lm.dim, lm.dim * 3) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } + return supported; + } +}; + +struct guard_temporal_fused_projection_layout_supported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + if (guard_temporal_split_projection_layout_supported{}(runtime_ev, ctx)) { + return false; + } + const auto &lm = runtime_ev.request.model.moshi_lm; + bool supported = lm.num_layers > 0; + for (int32_t layer_index = 0; layer_index < lm.num_layers; ++layer_index) { + const auto *projection = + ctx.session.contract.lm + .temporal_layers[static_cast(layer_index)] + .fused_input_projection.tensor; + supported = supported && + detail::tensor_shape(projection, lm.dim, lm.dim * 3) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } + return supported; + } +}; + +struct guard_temporal_projection_layout_unsupported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_temporal_split_projection_layout_supported{}(runtime_ev, + ctx) && + !guard_temporal_fused_projection_layout_supported{}(runtime_ev, ctx); + } +}; + struct guard_sampling_seed_nonzero { bool operator()(const event::initialize_run &runtime_ev, const action::context &) const noexcept { @@ -459,15 +544,11 @@ struct guard_temporal_kv_bind_failed { struct guard_temporal_layer_norm_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *norm1 = - detail::find_lm_transformer_tensor(model, layer, "norm1.alpha"); - return layer >= 0 && layer < model.moshi_lm.num_layers && hidden_dim > 0 && - static_cast(hidden_dim) <= ctx.capacity.hidden_dim && - detail::tensor_shape(norm1, hidden_dim) && - static_cast(norm1->type) == detail::dtype::f32; + return layer >= 0 && layer < runtime_ev.request.model.moshi_lm.num_layers && + hidden_dim > 0 && + static_cast(hidden_dim) <= ctx.capacity.hidden_dim; } }; @@ -509,18 +590,13 @@ struct guard_temporal_layer_norm_failed { struct guard_temporal_layer_projection_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *projection = - detail::find_lm_transformer_projection(model, layer); - return layer >= 0 && layer < model.moshi_lm.num_layers && hidden_dim > 0 && + return layer >= 0 && layer < runtime_ev.request.model.moshi_lm.num_layers && + hidden_dim > 0 && static_cast(hidden_dim) <= ctx.capacity.hidden_dim && static_cast(hidden_dim) * 3u <= - ctx.capacity.hidden_dim * 3u && - detail::tensor_shape(projection, hidden_dim, hidden_dim * 3) && - detail::supported_mul_mat_dtype( - static_cast(projection->type)); + ctx.capacity.hidden_dim * 3u; } }; @@ -690,14 +766,9 @@ struct guard_temporal_layer_out_projection_supported { const action::context &ctx) const noexcept { const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *projection = detail::find_lm_transformer_tensor( - runtime_ev.request.model, layer, "self_attn.out_projs.0.weight"); return runtime_ev.ctx.temporal_layer_attention_ok && layer >= 0 && layer < runtime_ev.request.model.moshi_lm.num_layers && - hidden_dim > 0 && - detail::tensor_shape(projection, hidden_dim, hidden_dim) && - detail::supported_mul_mat_dtype( - static_cast(projection->type)); + hidden_dim > 0; } }; @@ -739,16 +810,12 @@ struct guard_temporal_layer_residual_failed { struct guard_temporal_layer_norm2_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *norm2 = - detail::find_lm_transformer_tensor(model, layer, "norm2.alpha"); return runtime_ev.ctx.temporal_layer_residual_ok && layer >= 0 && - layer < model.moshi_lm.num_layers && hidden_dim > 0 && - static_cast(hidden_dim) <= ctx.capacity.hidden_dim && - detail::tensor_shape(norm2, hidden_dim) && - static_cast(norm2->type) == detail::dtype::f32; + layer < runtime_ev.request.model.moshi_lm.num_layers && + hidden_dim > 0 && + static_cast(hidden_dim) <= ctx.capacity.hidden_dim; } }; @@ -792,20 +859,9 @@ struct guard_temporal_layer_gating_in_supported { const action::context &ctx) const noexcept { const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *linear_in = detail::find_lm_transformer_tensor( - runtime_ev.request.model, layer, "gating.linear_in.weight"); - int64_t projection_dim = 0; - if (linear_in != nullptr && linear_in->n_dims > 1) { - projection_dim = linear_in->dims[1]; - } return runtime_ev.ctx.temporal_layer_norm2_ok && layer >= 0 && layer < runtime_ev.request.model.moshi_lm.num_layers && - hidden_dim > 0 && projection_dim > 0 && (projection_dim % 2) == 0 && - static_cast(projection_dim) <= - ctx.capacity.hidden_dim * 8u && - detail::tensor_shape(linear_in, hidden_dim, projection_dim) && - detail::supported_mul_mat_dtype( - static_cast(linear_in->type)); + hidden_dim > 0; } }; @@ -832,21 +888,11 @@ struct guard_temporal_layer_gating_in_failed { struct guard_temporal_layer_silu_gate_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - const auto *linear_in = detail::find_lm_transformer_tensor( - runtime_ev.request.model, runtime_ev.ctx.temporal_layer_index, - "gating.linear_in.weight"); - int64_t projection_dim = 0; - if (linear_in != nullptr && linear_in->n_dims > 1) { - projection_dim = linear_in->dims[1]; - } - const int64_t gate_dim = projection_dim / 2; + const action::context &) const noexcept { return runtime_ev.ctx.temporal_layer_gating_in_ok && runtime_ev.ctx.temporal_layer_index >= 0 && runtime_ev.ctx.temporal_layer_index < - runtime_ev.request.model.moshi_lm.num_layers && - gate_dim > 0 && - static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u; + runtime_ev.request.model.moshi_lm.num_layers; } }; @@ -890,22 +936,9 @@ struct guard_temporal_layer_gating_out_supported { const action::context &ctx) const noexcept { const int32_t hidden_dim = ctx.session.hidden_dim; const int32_t layer = runtime_ev.ctx.temporal_layer_index; - const auto *linear_in = detail::find_lm_transformer_tensor( - runtime_ev.request.model, layer, "gating.linear_in.weight"); - const auto *linear_out = detail::find_lm_transformer_tensor( - runtime_ev.request.model, layer, "gating.linear_out.weight"); - int64_t projection_dim = 0; - if (linear_in != nullptr && linear_in->n_dims > 1) { - projection_dim = linear_in->dims[1]; - } - const int64_t gate_dim = projection_dim / 2; return runtime_ev.ctx.temporal_layer_silu_gate_ok && layer >= 0 && layer < runtime_ev.request.model.moshi_lm.num_layers && - hidden_dim > 0 && gate_dim > 0 && - static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u && - detail::tensor_shape(linear_out, gate_dim, hidden_dim) && - detail::supported_mul_mat_dtype( - static_cast(linear_out->type)); + hidden_dim > 0; } }; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 8b7bb1ed..9b2b7ee1 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -14,6 +14,7 @@ namespace emel::speech::predictor::moshi::executor { struct state_uninitialized {}; struct state_bind_contract_decision {}; struct state_input_embedding_contract_decision {}; +struct state_temporal_projection_layout_decision {}; struct state_sampling_seed_decision {}; struct state_text_sampling_top_k_decision {}; struct state_audio_sampling_top_k_decision {}; @@ -181,7 +182,7 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_bind_contract_invalid{} ] / action::effect_mark_bind_failed{} - , sml::state <= + , sml::state <= sml::state + sml::completion [ guard::guard_bound_root_operands_supported{} ] @@ -190,6 +191,21 @@ struct model { + sml::completion [ guard::guard_bound_root_operands_unsupported{} ] / action::effect_mark_bind_failed{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_temporal_split_projection_layout_supported{} ] + / action::effect_bind_temporal_split_projection_layout{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_temporal_fused_projection_layout_supported{} ] + / action::effect_bind_temporal_fused_projection_layout{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_temporal_projection_layout_unsupported{} ] + / action::effect_mark_bind_failed{} , sml::state <= sml::state + sml::completion [ guard::guard_sampling_seed_nonzero{} ] / action::effect_bind_nonzero_sampling_seed{} diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index 227af044..9222afd5 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -512,6 +512,18 @@ TEST_CASE("enriched moshi lm fixture loads hparams, vocab, and contract") { } } CHECK(contract.lm.transformer.tensor_count > 0u); + for (int32_t layer_index = 0; layer_index < model.moshi_lm.num_layers; + ++layer_index) { + const auto &layer = + contract.lm.temporal_layers[static_cast(layer_index)]; + REQUIRE(layer.norm1.tensor != nullptr); + REQUIRE((layer.split_input_projection.tensor != nullptr || + layer.fused_input_projection.tensor != nullptr)); + REQUIRE(layer.output_projection.tensor != nullptr); + REQUIRE(layer.norm2.tensor != nullptr); + REQUIRE(layer.gating_input.tensor != nullptr); + REQUIRE(layer.gating_output.tensor != nullptr); + } CHECK(contract.lm.depformer.tensor_count > 0u); CHECK(contract.lm.linears.tensor_count == 4u); } diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 3c7983f9..94d75452 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -1509,6 +1509,37 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { CHECK(moshi_executor::guard::guard_bound_root_operands_unsupported{}( executor_init_run, executor_ctx)); executor_ctx.session.contract.lm.text_embedding.tensor = bound_text_embedding; + for (int32_t layer_index = 0; layer_index < lm.num_layers; ++layer_index) { + auto &layer = executor_ctx.session.contract.lm + .temporal_layers[static_cast(layer_index)]; + const auto *projection = layer.split_input_projection.tensor != nullptr + ? layer.split_input_projection.tensor + : layer.fused_input_projection.tensor; + REQUIRE(projection != nullptr); + layer.split_input_projection.tensor = projection; + layer.fused_input_projection.tensor = projection; + } + CHECK( + moshi_executor::guard::guard_temporal_split_projection_layout_supported{}( + executor_init_run, executor_ctx)); + moshi_executor::action::effect_bind_temporal_split_projection_layout{}( + executor_init_run, executor_ctx); + CHECK(executor_ctx.session.temporal_input_projections[0] == + executor_ctx.session.contract.lm.temporal_layers[0] + .split_input_projection.tensor); + for (int32_t layer_index = 0; layer_index < lm.num_layers; ++layer_index) { + executor_ctx.session.contract.lm + .temporal_layers[static_cast(layer_index)] + .split_input_projection.tensor = nullptr; + } + CHECK( + moshi_executor::guard::guard_temporal_fused_projection_layout_supported{}( + executor_init_run, executor_ctx)); + moshi_executor::action::effect_bind_temporal_fused_projection_layout{}( + executor_init_run, executor_ctx); + CHECK_FALSE( + moshi_executor::guard::guard_temporal_projection_layout_unsupported{}( + executor_init_run, executor_ctx)); executor_init.on_done = emel::callback:: from Date: Fri, 10 Jul 2026 23:59:14 -0500 Subject: [PATCH 33/61] perf: prebind moshi depformer layers --- .../speech_predictor_moshi_executor.mmd | 7 +- .../speech_predictor_moshi_executor.md | 14 +- src/emel/model/moshi/detail.cpp | 77 +++++++ src/emel/model/moshi/detail.hpp | 21 ++ .../predictor/moshi/executor/actions.hpp | 115 +++++++---- .../predictor/moshi/executor/context.hpp | 6 + .../predictor/moshi/executor/detail.hpp | 87 -------- .../predictor/moshi/executor/guards.hpp | 189 +++++++++++------- .../speech/predictor/moshi/executor/sm.hpp | 20 +- tests/model/moshi/binding_tests.cpp | 16 ++ .../predictor/moshi_executor_detail_tests.cpp | 36 ---- .../predictor/moshi_lifecycle_tests.cpp | 42 ++++ 12 files changed, 395 insertions(+), 235 deletions(-) diff --git a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd index c67a35b6..a5f2e0e5 100644 --- a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd +++ b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd @@ -6,9 +6,12 @@ stateDiagram-v2 state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ state_input_embedding_contract_decision --> state_temporal_projection_layout_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none state_input_embedding_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bound_root_operands_unsupported_] / effect_mark_bind_failed_ - state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_split_projection_layout_supported_] / effect_bind_temporal_split_projection_layout_ - state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_fused_projection_layout_supported_] / effect_bind_temporal_fused_projection_layout_ + state_temporal_projection_layout_decision --> state_depformer_projection_layout_decision : completion_initialize_run_ [guard_temporal_split_projection_layout_supported_] / effect_bind_temporal_split_projection_layout_ + state_temporal_projection_layout_decision --> state_depformer_projection_layout_decision : completion_initialize_run_ [guard_temporal_fused_projection_layout_supported_] / effect_bind_temporal_fused_projection_layout_ state_temporal_projection_layout_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_temporal_projection_layout_unsupported_] / effect_mark_bind_failed_ + state_depformer_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_depformer_split_projection_layout_supported_] / effect_bind_depformer_split_projection_layout_ + state_depformer_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_depformer_fused_projection_layout_supported_] / effect_bind_depformer_fused_projection_layout_ + state_depformer_projection_layout_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_depformer_projection_layout_unsupported_] / effect_mark_bind_failed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ diff --git a/.planning/architecture/speech_predictor_moshi_executor.md b/.planning/architecture/speech_predictor_moshi_executor.md index ec109204..d763d6e9 100644 --- a/.planning/architecture/speech_predictor_moshi_executor.md +++ b/.planning/architecture/speech_predictor_moshi_executor.md @@ -13,9 +13,12 @@ stateDiagram-v2 state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ state_input_embedding_contract_decision --> state_temporal_projection_layout_decision : completion_initialize_run_ [guard_bound_root_operands_supported_] / none state_input_embedding_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bound_root_operands_unsupported_] / effect_mark_bind_failed_ - state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_split_projection_layout_supported_] / effect_bind_temporal_split_projection_layout_ - state_temporal_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_temporal_fused_projection_layout_supported_] / effect_bind_temporal_fused_projection_layout_ + state_temporal_projection_layout_decision --> state_depformer_projection_layout_decision : completion_initialize_run_ [guard_temporal_split_projection_layout_supported_] / effect_bind_temporal_split_projection_layout_ + state_temporal_projection_layout_decision --> state_depformer_projection_layout_decision : completion_initialize_run_ [guard_temporal_fused_projection_layout_supported_] / effect_bind_temporal_fused_projection_layout_ state_temporal_projection_layout_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_temporal_projection_layout_unsupported_] / effect_mark_bind_failed_ + state_depformer_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_depformer_split_projection_layout_supported_] / effect_bind_depformer_split_projection_layout_ + state_depformer_projection_layout_decision --> state_sampling_seed_decision : completion_initialize_run_ [guard_depformer_fused_projection_layout_supported_] / effect_bind_depformer_fused_projection_layout_ + state_depformer_projection_layout_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_depformer_projection_layout_unsupported_] / effect_mark_bind_failed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_nonzero_] / effect_bind_nonzero_sampling_seed_ state_sampling_seed_decision --> state_text_sampling_top_k_decision : completion_initialize_run_ [guard_sampling_seed_zero_] / effect_bind_zero_sampling_seed_ state_text_sampling_top_k_decision --> state_audio_sampling_top_k_decision : completion_initialize_run_ [guard_text_sampling_top_k_within_card_] / effect_bind_requested_text_sampling_top_k_ @@ -303,9 +306,12 @@ stateDiagram-v2 | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bound_root_operands_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_input_embedding_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_bound_root_operands_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_split_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_split_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_fused_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_fused_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_split_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_split_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_fused_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_temporal_fused_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_depformer_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_temporal_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_projection_layout_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_split_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_split_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_fused_projection_layout_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_depformer_fused_projection_layout>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_depformer_projection_layout_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_depformer_projection_layout_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_nonzero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_nonzero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_sampling_seed_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_seed_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_zero_sampling_seed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_sampling_top_k_within_card>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_requested_text_sampling_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_audio_sampling_top_k_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index 99847b69..37080622 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -853,10 +853,87 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, } } + if (lm.depformer_num_layers > + emel::model::data::moshi_lm_hparams::k_max_delays) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } for (int32_t block = 0; block < lm.depformer_num_layers; ++block) { if (!has_depformer_block(model_data, block)) { return emel::error::cast(emel::model::loader::error::model_invalid); } + auto &layer = contract_out.depformer_layers[static_cast(block)]; + char name[160] = {}; + int written = std::snprintf(name, sizeof(name), + "lm.depformer.layers.%d.norm1.alpha", block); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor( + model_data, std::string_view{name, static_cast(written)}, + layer.norm1)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + written = std::snprintf(name, sizeof(name), + "lm.depformer.layers.%d.norm2.alpha", block); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor( + model_data, std::string_view{name, static_cast(written)}, + layer.norm2)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + auto &codebook_layer = layer.codebooks[static_cast(codebook)]; + written = + std::snprintf(name, sizeof(name), + "lm.depformer.layers.%d.self_attn.in_projs.%d.weight", + block, codebook); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + (void)bind_exact_tensor( + model_data, std::string_view{name, static_cast(written)}, + codebook_layer.split_input_projection); + written = std::snprintf( + name, sizeof(name), + "lm.depformer.layers.%d.self_attn.in_proj_weight", block); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + (void)bind_exact_tensor( + model_data, std::string_view{name, static_cast(written)}, + codebook_layer.fused_input_projection); + written = std::snprintf( + name, sizeof(name), + "lm.depformer.layers.%d.self_attn.out_projs.%d.weight", block, + codebook); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor( + model_data, + std::string_view{name, static_cast(written)}, + codebook_layer.output_projection)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + written = + std::snprintf(name, sizeof(name), + "lm.depformer.layers.%d.gating.%d.linear_in.weight", + block, codebook); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor( + model_data, + std::string_view{name, static_cast(written)}, + codebook_layer.gating_input)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + written = + std::snprintf(name, sizeof(name), + "lm.depformer.layers.%d.gating.%d.linear_out.weight", + block, codebook); + if (written <= 0 || static_cast(written) >= sizeof(name) || + !bind_exact_tensor( + model_data, + std::string_view{name, static_cast(written)}, + codebook_layer.gating_output)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + } } } diff --git a/src/emel/model/moshi/detail.hpp b/src/emel/model/moshi/detail.hpp index e4d98c01..88b4d304 100644 --- a/src/emel/model/moshi/detail.hpp +++ b/src/emel/model/moshi/detail.hpp @@ -46,6 +46,23 @@ struct temporal_layer_contract { tensor_view gating_output = {}; }; +struct depformer_codebook_layer_contract { + tensor_view split_input_projection = {}; + tensor_view fused_input_projection = {}; + tensor_view output_projection = {}; + tensor_view gating_input = {}; + tensor_view gating_output = {}; +}; + +struct depformer_layer_contract { + tensor_view norm1 = {}; + tensor_view norm2 = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + codebooks = {}; +}; + struct lm_contract { family_view text_emb = {}; family_view audio_emb = {}; @@ -81,6 +98,10 @@ struct lm_contract { static_cast( emel::model::data::moshi_lm_hparams::k_max_delays)> temporal_layers = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)> + depformer_layers = {}; }; struct mimi_contract { diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index f6974789..5879e26f 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -65,6 +65,36 @@ struct effect_bind_temporal_fused_projection_layout { } }; +struct effect_bind_depformer_split_projection_layout { + void operator()(const event::initialize_run &, context &ctx) const noexcept { + const auto &lm = ctx.session.model->moshi_lm; + for (int32_t layer = 0; layer < lm.depformer_num_layers; ++layer) { + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + ctx.session.depformer_input_projections[static_cast(layer)] + [static_cast(codebook)] = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(codebook)] + .split_input_projection.tensor; + } + } + } +}; + +struct effect_bind_depformer_fused_projection_layout { + void operator()(const event::initialize_run &, context &ctx) const noexcept { + const auto &lm = ctx.session.model->moshi_lm; + for (int32_t layer = 0; layer < lm.depformer_num_layers; ++layer) { + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + ctx.session.depformer_input_projections[static_cast(layer)] + [static_cast(codebook)] = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(codebook)] + .fused_input_projection.tensor; + } + } + } +}; + struct effect_bind_nonzero_sampling_seed { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { @@ -1263,7 +1293,8 @@ struct effect_run_depformer_layer_norm_scale { runtime_ev.ctx.depformer_layer_norm_ok = false; const auto *norm1 = - detail::find_depformer_tensor(model, layer, "norm1.alpha"); + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .norm1.tensor; const auto *alpha = static_cast(norm1->data); emel::kernel::event::op_mul mul_ev{ @@ -1278,9 +1309,9 @@ struct effect_run_depformer_layer_norm_scale { }; struct effect_bind_depformer_layer_projection { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; @@ -1291,7 +1322,8 @@ struct effect_bind_depformer_layer_projection { 0.0f); const auto *projection = - detail::find_depformer_projection(model, layer, weight_index); + ctx.session.depformer_input_projections[static_cast( + layer)][static_cast(weight_index)]; runtime_ev.ctx.projection_view_bound = detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); } @@ -1423,7 +1455,8 @@ struct effect_run_depformer_layer_attention { }; struct effect_bind_depformer_layer_out_projection { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; @@ -1435,8 +1468,10 @@ struct effect_bind_depformer_layer_out_projection { std::fill_n(runtime_ev.ctx.projection.data(), static_cast(dep_dim), 0.0f); - const auto *projection = detail::find_depformer_codebook_tensor( - model, layer, "self_attn.out_projs.%d.weight", weight_index); + const auto *projection = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(weight_index)] + .output_projection.tensor; runtime_ev.ctx.projection_view_bound = detail::bind_tensor_view(*projection, runtime_ev.ctx.projection_view); } @@ -1505,7 +1540,8 @@ struct effect_run_depformer_layer_norm2_scale { runtime_ev.ctx.depformer_layer_norm2_ok = false; const auto *norm2 = - detail::find_depformer_tensor(model, layer, "norm2.alpha"); + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .norm2.tensor; const auto *alpha = static_cast(norm2->data); emel::kernel::event::op_mul mul_ev{ @@ -1520,12 +1556,14 @@ struct effect_run_depformer_layer_norm2_scale { }; struct effect_bind_depformer_layer_gating_in { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - const auto &model = runtime_ev.request.model; + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { const int32_t layer = runtime_ev.ctx.depformer_layer_index; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; - const auto *linear_in = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_in.weight", weight_index); + const auto *linear_in = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(weight_index)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); runtime_ev.ctx.depformer_layer_gating_in_ok = false; runtime_ev.ctx.projection_view_bound = false; @@ -1541,12 +1579,13 @@ struct effect_bind_depformer_layer_gating_in { struct effect_run_depformer_layer_gating_in { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const int32_t dep_dim = model.moshi_lm.depformer_dim; + const int32_t dep_dim = runtime_ev.request.model.moshi_lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; - const auto *linear_in = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_in.weight", weight_index); + const auto *linear_in = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(weight_index)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); runtime_ev.ctx.depformer_layer_gating_in_ok = false; emel::kernel::event::op_mul_mat projection_ev{ @@ -1564,9 +1603,12 @@ struct effect_run_depformer_layer_gating_in { struct effect_run_depformer_layer_silu_gate_silu { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto *linear_in = detail::find_depformer_codebook_tensor( - runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, - "gating.%d.linear_in.weight", runtime_ev.ctx.depformer_weight_index); + const auto *linear_in = ctx.session.contract.lm + .depformer_layers[static_cast( + runtime_ev.ctx.depformer_layer_index)] + .codebooks[static_cast( + runtime_ev.ctx.depformer_weight_index)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); const uint64_t gate_dim = projection_dim / 2u; runtime_ev.ctx.depformer_layer_silu_gate_silu_ok = false; @@ -1591,9 +1633,12 @@ struct effect_run_depformer_layer_silu_gate_silu { struct effect_run_depformer_layer_silu_gate_mul { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto *linear_in = detail::find_depformer_codebook_tensor( - runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, - "gating.%d.linear_in.weight", runtime_ev.ctx.depformer_weight_index); + const auto *linear_in = ctx.session.contract.lm + .depformer_layers[static_cast( + runtime_ev.ctx.depformer_layer_index)] + .codebooks[static_cast( + runtime_ev.ctx.depformer_weight_index)] + .gating_input.tensor; const uint64_t projection_dim = static_cast(linear_in->dims[1]); const uint64_t gate_dim = projection_dim / 2u; const float *right = runtime_ev.ctx.gating_projection.data() + gate_dim; @@ -1611,16 +1656,17 @@ struct effect_run_depformer_layer_silu_gate_mul { }; struct effect_bind_depformer_layer_gating_out { - void operator()(const event::step_run &runtime_ev, context &) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; - const auto *linear_in = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_in.weight", weight_index); - const auto *linear_out = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_out.weight", weight_index); + const auto &codebook_layer = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(weight_index)]; + const auto *linear_in = codebook_layer.gating_input.tensor; + const auto *linear_out = codebook_layer.gating_output.tensor; const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; (void)gate_dim; runtime_ev.ctx.depformer_layer_gating_out_ok = false; @@ -1637,13 +1683,14 @@ struct effect_bind_depformer_layer_gating_out { struct effect_run_depformer_layer_gating_out { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const auto &lm = model.moshi_lm; + const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; - const auto *linear_in = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_in.weight", weight_index); + const auto *linear_in = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(weight_index)] + .gating_input.tensor; const uint64_t gate_dim = static_cast(linear_in->dims[1]) / 2u; runtime_ev.ctx.depformer_layer_gating_out_ok = false; emel::kernel::event::op_mul_mat projection_ev{ diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index f884be3d..c9bea34f 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -54,6 +54,12 @@ struct runtime { static_cast( emel::model::data::moshi_lm_hparams::k_max_delays)> temporal_input_projections = {}; + std::array( + emel::model::data::moshi_lm_hparams::k_max_delays)>, + static_cast( + emel::model::data::moshi_lm_hparams::k_max_delays)> + depformer_input_projections = {}; }; struct sampling_config { diff --git a/src/emel/speech/predictor/moshi/executor/detail.hpp b/src/emel/speech/predictor/moshi/executor/detail.hpp index 4bfa9d51..e06a4b6c 100644 --- a/src/emel/speech/predictor/moshi/executor/detail.hpp +++ b/src/emel/speech/predictor/moshi/executor/detail.hpp @@ -1,10 +1,8 @@ #pragma once #include -#include #include #include -#include #include "emel/kernel/detail.hpp" #include "emel/kernel/events.hpp" @@ -49,91 +47,6 @@ void fill_default_nb(tensor_type &tensor) noexcept { tensor.nb[3] = tensor.nb[2] * tensor.ne[2]; } -inline const tensor_record *find_tensor(const emel::model::data &model, - const std::string_view name) noexcept { - for (uint32_t index = 0u; index < model.n_tensors; ++index) { - const auto &tensor = model.tensors[index]; - if (emel::model::tensor_name_view(model, tensor) == name) { - return &tensor; - } - } - return nullptr; -} - -inline const tensor_record *find_indexed_tensor(const emel::model::data &model, - const char *format, - const int32_t index) noexcept { - char buffer[96] = {}; - const int written = std::snprintf(buffer, sizeof(buffer), format, index); - if (written <= 0 || static_cast(written) >= sizeof(buffer)) { - return nullptr; - } - return find_tensor(model, - std::string_view{buffer, static_cast(written)}); -} - -inline const tensor_record * -find_lm_transformer_tensor(const emel::model::data &model, const int32_t layer, - const char *suffix) noexcept { - char buffer[128] = {}; - const int written = std::snprintf( - buffer, sizeof(buffer), "lm.transformer.layers.%d.%s", layer, suffix); - if (written <= 0 || static_cast(written) >= sizeof(buffer)) { - return nullptr; - } - return find_tensor(model, - std::string_view{buffer, static_cast(written)}); -} - -inline const tensor_record * -find_lm_transformer_projection(const emel::model::data &model, - const int32_t layer) noexcept { - const auto *split = - find_lm_transformer_tensor(model, layer, "self_attn.in_projs.0.weight"); - if (split != nullptr) { - return split; - } - return find_lm_transformer_tensor(model, layer, "self_attn.in_proj_weight"); -} - -inline const tensor_record * -find_depformer_tensor(const emel::model::data &model, const int32_t layer, - const char *suffix) noexcept { - char buffer[160] = {}; - const int written = std::snprintf(buffer, sizeof(buffer), - "lm.depformer.layers.%d.%s", layer, suffix); - if (written <= 0 || static_cast(written) >= sizeof(buffer)) { - return nullptr; - } - return find_tensor(model, - std::string_view{buffer, static_cast(written)}); -} - -inline const tensor_record * -find_depformer_codebook_tensor(const emel::model::data &model, - const int32_t layer, const char *format, - const int32_t codebook) noexcept { - char suffix[128] = {}; - const int suffix_written = - std::snprintf(suffix, sizeof(suffix), format, codebook); - if (suffix_written <= 0 || - static_cast(suffix_written) >= sizeof(suffix)) { - return nullptr; - } - return find_depformer_tensor(model, layer, suffix); -} - -inline const tensor_record * -find_depformer_projection(const emel::model::data &model, const int32_t layer, - const int32_t codebook) noexcept { - const auto *split = find_depformer_codebook_tensor( - model, layer, "self_attn.in_projs.%d.weight", codebook); - if (split != nullptr) { - return split; - } - return find_depformer_tensor(model, layer, "self_attn.in_proj_weight"); -} - inline bool supported_get_rows_dtype(const dtype type) noexcept { const auto code = emel::kernel::detail::dtype_code(type); return code == emel::kernel::detail::dtype_f32 || diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index f5665211..02ebc69a 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -143,6 +143,48 @@ struct guard_bound_root_operands_supported { detail::supported_mul_mat_dtype( static_cast(gating_output->type)); } + for (int32_t layer_index = 0; layer_index < lm.depformer_num_layers; + ++layer_index) { + const auto &layer = + ctx.session.contract.lm + .depformer_layers[static_cast(layer_index)]; + const auto *norm1 = layer.norm1.tensor; + const auto *norm2 = layer.norm2.tensor; + supported = + supported && detail::tensor_shape(norm1, dep_dim) && + static_cast(norm1->type) == detail::dtype::f32 && + detail::tensor_shape(norm2, dep_dim) && + static_cast(norm2->type) == detail::dtype::f32; + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + const auto &codebook_layer = + layer.codebooks[static_cast(codebook)]; + const auto *output_projection = codebook_layer.output_projection.tensor; + const auto *gating_input = codebook_layer.gating_input.tensor; + const auto *gating_output = codebook_layer.gating_output.tensor; + int64_t gating_projection_dim = 0; + if (gating_input != nullptr && gating_input->n_dims > 1) { + gating_projection_dim = gating_input->dims[1]; + } + const int64_t gating_dim = gating_projection_dim / 2; + supported = + supported && + detail::tensor_shape(output_projection, dep_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(output_projection->type)) && + gating_projection_dim > 0 && (gating_projection_dim % 2) == 0 && + static_cast(gating_projection_dim) <= + ctx.capacity.hidden_dim * 8u && + detail::tensor_shape(gating_input, dep_dim, + gating_projection_dim) && + detail::supported_mul_mat_dtype( + static_cast(gating_input->type)) && + gating_dim > 0 && + static_cast(gating_dim) <= ctx.capacity.hidden_dim * 4u && + detail::tensor_shape(gating_output, gating_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(gating_output->type)); + } + } return supported; } }; @@ -204,6 +246,67 @@ struct guard_temporal_projection_layout_unsupported { } }; +struct guard_depformer_split_projection_layout_supported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + const auto &lm = runtime_ev.request.model.moshi_lm; + bool supported = lm.depformer_num_layers > 0 && lm.dep_q > 0; + for (int32_t layer_index = 0; layer_index < lm.depformer_num_layers; + ++layer_index) { + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + const auto *projection = + ctx.session.contract.lm + .depformer_layers[static_cast(layer_index)] + .codebooks[static_cast(codebook)] + .split_input_projection.tensor; + supported = supported && + detail::tensor_shape(projection, lm.depformer_dim, + lm.depformer_dim * 3) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } + } + return supported; + } +}; + +struct guard_depformer_fused_projection_layout_supported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + if (guard_depformer_split_projection_layout_supported{}(runtime_ev, ctx)) { + return false; + } + const auto &lm = runtime_ev.request.model.moshi_lm; + bool supported = lm.depformer_num_layers > 0 && lm.dep_q > 0; + for (int32_t layer_index = 0; layer_index < lm.depformer_num_layers; + ++layer_index) { + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + const auto *projection = + ctx.session.contract.lm + .depformer_layers[static_cast(layer_index)] + .codebooks[static_cast(codebook)] + .fused_input_projection.tensor; + supported = supported && + detail::tensor_shape(projection, lm.depformer_dim, + lm.depformer_dim * 3) && + detail::supported_mul_mat_dtype( + static_cast(projection->type)); + } + } + return supported; + } +}; + +struct guard_depformer_projection_layout_unsupported { + bool operator()(const event::initialize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_depformer_split_projection_layout_supported{}(runtime_ev, + ctx) && + !guard_depformer_fused_projection_layout_supported{}(runtime_ev, + ctx); + } +}; + struct guard_sampling_seed_nonzero { bool operator()(const event::initialize_run &runtime_ev, const action::context &) const noexcept { @@ -1453,16 +1556,12 @@ struct guard_depformer_input_projection_embedding_unsupported { struct guard_depformer_layer_norm_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const int32_t dep_dim = model.moshi_lm.depformer_dim; + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; - const auto *norm1 = - detail::find_depformer_tensor(model, layer, "norm1.alpha"); return runtime_ev.ctx.depformer_input_ok && layer >= 0 && - layer < model.moshi_lm.depformer_num_layers && dep_dim > 0 && - static_cast(dep_dim) <= ctx.capacity.hidden_dim && - detail::tensor_shape(norm1, dep_dim) && - static_cast(norm1->type) == detail::dtype::f32; + layer < lm.depformer_num_layers && dep_dim > 0 && + static_cast(dep_dim) <= ctx.capacity.hidden_dim; } }; @@ -1513,16 +1612,10 @@ struct guard_depformer_layer_projection_supported { if (weight_index < 0 || weight_index >= lm.dep_q) { return false; } - const auto *projection = - detail::find_depformer_projection(model, layer, weight_index); return runtime_ev.ctx.depformer_layer_norm_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && codebook < model.moshi_lm.dep_q && dep_dim > 0 && - static_cast(dep_dim) * 3u <= - ctx.capacity.hidden_dim * 3u && - detail::tensor_shape(projection, dep_dim, dep_dim * 3) && - detail::supported_mul_mat_dtype( - static_cast(projection->type)); + static_cast(dep_dim) * 3u <= ctx.capacity.hidden_dim * 3u; } }; @@ -1667,14 +1760,9 @@ struct guard_depformer_layer_out_projection_supported { if (weight_index < 0 || weight_index >= lm.dep_q) { return false; } - const auto *projection = detail::find_depformer_codebook_tensor( - model, layer, "self_attn.out_projs.%d.weight", weight_index); return runtime_ev.ctx.depformer_layer_attention_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && - codebook < model.moshi_lm.dep_q && dep_dim > 0 && - detail::tensor_shape(projection, dep_dim, dep_dim) && - detail::supported_mul_mat_dtype( - static_cast(projection->type)); + codebook < model.moshi_lm.dep_q && dep_dim > 0; } }; @@ -1716,16 +1804,12 @@ struct guard_depformer_layer_residual_failed { struct guard_depformer_layer_norm2_supported { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - const auto &model = runtime_ev.request.model; - const int32_t dep_dim = model.moshi_lm.depformer_dim; + const auto &lm = runtime_ev.request.model.moshi_lm; + const int32_t dep_dim = lm.depformer_dim; const int32_t layer = runtime_ev.ctx.depformer_layer_index; - const auto *norm2 = - detail::find_depformer_tensor(model, layer, "norm2.alpha"); return runtime_ev.ctx.depformer_layer_residual_ok && layer >= 0 && - layer < model.moshi_lm.depformer_num_layers && dep_dim > 0 && - static_cast(dep_dim) <= ctx.capacity.hidden_dim && - detail::tensor_shape(norm2, dep_dim) && - static_cast(norm2->type) == detail::dtype::f32; + layer < lm.depformer_num_layers && dep_dim > 0 && + static_cast(dep_dim) <= ctx.capacity.hidden_dim; } }; @@ -1766,7 +1850,7 @@ struct guard_depformer_layer_norm2_failed { struct guard_depformer_layer_gating_in_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { + const action::context &) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; @@ -1776,21 +1860,9 @@ struct guard_depformer_layer_gating_in_supported { if (weight_index < 0 || weight_index >= lm.dep_q) { return false; } - const auto *linear_in = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_in.weight", weight_index); - int64_t projection_dim = 0; - if (linear_in != nullptr && linear_in->n_dims > 1) { - projection_dim = linear_in->dims[1]; - } return runtime_ev.ctx.depformer_layer_norm2_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && - codebook < model.moshi_lm.dep_q && dep_dim > 0 && - projection_dim > 0 && (projection_dim % 2) == 0 && - static_cast(projection_dim) <= - ctx.capacity.hidden_dim * 8u && - detail::tensor_shape(linear_in, dep_dim, projection_dim) && - detail::supported_mul_mat_dtype( - static_cast(linear_in->type)); + codebook < model.moshi_lm.dep_q && dep_dim > 0; } }; @@ -1817,7 +1889,7 @@ struct guard_depformer_layer_gating_in_failed { struct guard_depformer_layer_silu_gate_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { + const action::context &) const noexcept { const auto &lm = runtime_ev.request.model.moshi_lm; const int32_t codebook = runtime_ev.ctx.depformer_codebook_index; const int32_t weight_index = runtime_ev.ctx.depformer_weight_index; @@ -1825,20 +1897,10 @@ struct guard_depformer_layer_silu_gate_supported { codebook >= lm.dep_q) { return false; } - const auto *linear_in = detail::find_depformer_codebook_tensor( - runtime_ev.request.model, runtime_ev.ctx.depformer_layer_index, - "gating.%d.linear_in.weight", weight_index); - int64_t projection_dim = 0; - if (linear_in != nullptr && linear_in->n_dims > 1) { - projection_dim = linear_in->dims[1]; - } - const int64_t gate_dim = projection_dim / 2; return runtime_ev.ctx.depformer_layer_gating_in_ok && runtime_ev.ctx.depformer_layer_index >= 0 && runtime_ev.ctx.depformer_layer_index < - runtime_ev.request.model.moshi_lm.depformer_num_layers && - gate_dim > 0 && - static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u; + runtime_ev.request.model.moshi_lm.depformer_num_layers; } }; @@ -1879,7 +1941,7 @@ struct guard_depformer_layer_silu_gate_failed { struct guard_depformer_layer_gating_out_supported { bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { + const action::context &) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; const int32_t dep_dim = lm.depformer_dim; @@ -1889,22 +1951,9 @@ struct guard_depformer_layer_gating_out_supported { if (weight_index < 0 || weight_index >= lm.dep_q) { return false; } - const auto *linear_in = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_in.weight", weight_index); - const auto *linear_out = detail::find_depformer_codebook_tensor( - model, layer, "gating.%d.linear_out.weight", weight_index); - int64_t projection_dim = 0; - if (linear_in != nullptr && linear_in->n_dims > 1) { - projection_dim = linear_in->dims[1]; - } - const int64_t gate_dim = projection_dim / 2; return runtime_ev.ctx.depformer_layer_silu_gate_ok && layer >= 0 && layer < model.moshi_lm.depformer_num_layers && codebook >= 0 && - codebook < model.moshi_lm.dep_q && dep_dim > 0 && gate_dim > 0 && - static_cast(gate_dim) <= ctx.capacity.hidden_dim * 4u && - detail::tensor_shape(linear_out, gate_dim, dep_dim) && - detail::supported_mul_mat_dtype( - static_cast(linear_out->type)); + codebook < model.moshi_lm.dep_q && dep_dim > 0; } }; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 9b2b7ee1..900a92e5 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -15,6 +15,7 @@ struct state_uninitialized {}; struct state_bind_contract_decision {}; struct state_input_embedding_contract_decision {}; struct state_temporal_projection_layout_decision {}; +struct state_depformer_projection_layout_decision {}; struct state_sampling_seed_decision {}; struct state_text_sampling_top_k_decision {}; struct state_audio_sampling_top_k_decision {}; @@ -191,12 +192,12 @@ struct model { + sml::completion [ guard::guard_bound_root_operands_unsupported{} ] / action::effect_mark_bind_failed{} - , sml::state <= + , sml::state <= sml::state + sml::completion [ guard::guard_temporal_split_projection_layout_supported{} ] / action::effect_bind_temporal_split_projection_layout{} - , sml::state <= + , sml::state <= sml::state + sml::completion [ guard::guard_temporal_fused_projection_layout_supported{} ] @@ -206,6 +207,21 @@ struct model { + sml::completion [ guard::guard_temporal_projection_layout_unsupported{} ] / action::effect_mark_bind_failed{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_depformer_split_projection_layout_supported{} ] + / action::effect_bind_depformer_split_projection_layout{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_depformer_fused_projection_layout_supported{} ] + / action::effect_bind_depformer_fused_projection_layout{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_depformer_projection_layout_unsupported{} ] + / action::effect_mark_bind_failed{} , sml::state <= sml::state + sml::completion [ guard::guard_sampling_seed_nonzero{} ] / action::effect_bind_nonzero_sampling_seed{} diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index 9222afd5..2223204a 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -524,6 +524,22 @@ TEST_CASE("enriched moshi lm fixture loads hparams, vocab, and contract") { REQUIRE(layer.gating_input.tensor != nullptr); REQUIRE(layer.gating_output.tensor != nullptr); } + for (int32_t layer_index = 0; + layer_index < model.moshi_lm.depformer_num_layers; ++layer_index) { + const auto &layer = + contract.lm.depformer_layers[static_cast(layer_index)]; + REQUIRE(layer.norm1.tensor != nullptr); + REQUIRE(layer.norm2.tensor != nullptr); + for (int32_t codebook = 0; codebook < model.moshi_lm.dep_q; ++codebook) { + const auto &codebook_layer = + layer.codebooks[static_cast(codebook)]; + REQUIRE((codebook_layer.split_input_projection.tensor != nullptr || + codebook_layer.fused_input_projection.tensor != nullptr)); + REQUIRE(codebook_layer.output_projection.tensor != nullptr); + REQUIRE(codebook_layer.gating_input.tensor != nullptr); + REQUIRE(codebook_layer.gating_output.tensor != nullptr); + } + } CHECK(contract.lm.depformer.tensor_count > 0u); CHECK(contract.lm.linears.tensor_count == 4u); } diff --git a/tests/speech/predictor/moshi_executor_detail_tests.cpp b/tests/speech/predictor/moshi_executor_detail_tests.cpp index ab5436d6..e61ade51 100644 --- a/tests/speech/predictor/moshi_executor_detail_tests.cpp +++ b/tests/speech/predictor/moshi_executor_detail_tests.cpp @@ -1,17 +1,14 @@ #include #include -#include #include #include "emel/kernel/detail.hpp" #include "emel/speech/predictor/moshi/executor/detail.hpp" -#include "moshi_fixture.hpp" namespace { namespace detail = emel::speech::predictor::moshi::executor::detail; -using emel::speech::predictor::moshi::test::load_fixture_or_skip; detail::dtype dtype(const uint8_t code) { return static_cast(code); @@ -95,36 +92,3 @@ TEST_CASE("speech Moshi executor classifies supported operand dtypes") { CHECK_FALSE( detail::supported_mul_mat_dtype(dtype(emel::kernel::detail::dtype_i32))); } - -TEST_CASE("speech Moshi executor resolves model tensor families") { - auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); - if (fixture.model == nullptr) { - return; - } - - const auto &model = *fixture.model; - CHECK(detail::find_tensor(model, "lm.text_emb.weight") != nullptr); - CHECK(detail::find_tensor(model, "missing.tensor") == nullptr); - CHECK(detail::find_indexed_tensor(model, "lm.emb.%d.weight", 0) != nullptr); - CHECK(detail::find_lm_transformer_projection(model, 0) != nullptr); - CHECK(detail::find_depformer_projection(model, 0, 0) != nullptr); - CHECK(detail::find_depformer_codebook_tensor( - model, 0, "self_attn.in_projs.%d.weight", 0) != nullptr); - - const std::array long_name = [] { - std::array value{}; - value.fill('x'); - value.back() = '\0'; - return value; - }(); - CHECK(detail::find_indexed_tensor(model, long_name.data(), 0) == nullptr); - CHECK(detail::find_lm_transformer_tensor(model, 0, long_name.data()) == - nullptr); - CHECK(detail::find_depformer_tensor(model, 0, long_name.data()) == nullptr); - CHECK(detail::find_depformer_codebook_tensor(model, 0, long_name.data(), 0) == - nullptr); - - auto empty_model = std::make_unique(); - CHECK(detail::find_lm_transformer_projection(*empty_model, 0) == nullptr); - CHECK(detail::find_depformer_projection(*empty_model, 0, 0) == nullptr); -} diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 94d75452..214e7403 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -1540,6 +1540,48 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { CHECK_FALSE( moshi_executor::guard::guard_temporal_projection_layout_unsupported{}( executor_init_run, executor_ctx)); + for (int32_t layer_index = 0; layer_index < lm.depformer_num_layers; + ++layer_index) { + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + auto &codebook_layer = + executor_ctx.session.contract.lm + .depformer_layers[static_cast(layer_index)] + .codebooks[static_cast(codebook)]; + const auto *projection = + codebook_layer.split_input_projection.tensor != nullptr + ? codebook_layer.split_input_projection.tensor + : codebook_layer.fused_input_projection.tensor; + REQUIRE(projection != nullptr); + codebook_layer.split_input_projection.tensor = projection; + codebook_layer.fused_input_projection.tensor = projection; + } + } + CHECK(moshi_executor::guard:: + guard_depformer_split_projection_layout_supported{}( + executor_init_run, executor_ctx)); + moshi_executor::action::effect_bind_depformer_split_projection_layout{}( + executor_init_run, executor_ctx); + CHECK(executor_ctx.session.depformer_input_projections[0][0] == + executor_ctx.session.contract.lm.depformer_layers[0] + .codebooks[0] + .split_input_projection.tensor); + for (int32_t layer_index = 0; layer_index < lm.depformer_num_layers; + ++layer_index) { + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + executor_ctx.session.contract.lm + .depformer_layers[static_cast(layer_index)] + .codebooks[static_cast(codebook)] + .split_input_projection.tensor = nullptr; + } + } + CHECK(moshi_executor::guard:: + guard_depformer_fused_projection_layout_supported{}( + executor_init_run, executor_ctx)); + moshi_executor::action::effect_bind_depformer_fused_projection_layout{}( + executor_init_run, executor_ctx); + CHECK_FALSE( + moshi_executor::guard::guard_depformer_projection_layout_unsupported{}( + executor_init_run, executor_ctx)); executor_init.on_done = emel::callback:: from Date: Sat, 11 Jul 2026 00:20:03 -0500 Subject: [PATCH 34/61] refactor: plan speech frames in generic generator --- docs/benchmarking.md | 11 ++-- src/emel/speech/generator/actions.hpp | 49 ++++++++++++++- src/emel/speech/generator/context.hpp | 7 +++ src/emel/speech/generator/errors.hpp | 1 + src/emel/speech/generator/events.hpp | 2 + src/emel/speech/generator/guards.hpp | 6 +- src/emel/speech/generator/sm.hpp | 26 ++++++-- src/emel/speech/predictor/moshi/actions.hpp | 16 +++-- src/emel/speech/predictor/moshi/context.hpp | 2 + src/emel/speech/predictor/moshi/events.hpp | 11 +++- src/emel/speech/predictor/moshi/guards.hpp | 10 ++- tests/speech/generator/lifecycle_tests.cpp | 61 ++++++++++++++++++- .../predictor/moshi_lifecycle_tests.cpp | 20 +++--- .../bench/speech/personaplex_emel_runner.cpp | 15 +++++ 14 files changed, 201 insertions(+), 36 deletions(-) diff --git a/docs/benchmarking.md b/docs/benchmarking.md index d7cd7f51..8c3f7e7e 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -387,10 +387,13 @@ on macOS, the default input is generated with Samantha at 175 words per minute s `--audio /path/to/input.wav` on another Unix host or to use an existing recording. the comparison builds two isolated Release executables. `personaplex_emel_runner` links only EMEL -and drives the maintained Mimi and Moshi state machines. `moshi_reference_driver personaplex` links -only the pinned moshi.cpp/ggml reference lane. the reference configure hard-disables Metal and the -script injects `--threads 1`, seed `1234`, 125 frames, temperatures, and sampling limits; there are -no process-global EMEL sampling defaults. +and drives the maintained generic speech generator with injected Mimi, batch-planner, tokenizer, +Moshi predictor, sampler, streaming-memory, and decoder actors. Each streamed or flushed frame is +planned through the shared batch planner before prediction; the typed one-frame plan is validated +by the predictor before memory allocation and graph execution. `moshi_reference_driver +personaplex` links only the pinned moshi.cpp/ggml reference lane. the reference configure +hard-disables Metal and the script injects `--threads 1`, seed `1234`, 125 frames, temperatures, +and sampling limits; there are no process-global EMEL sampling defaults. the pinned upstream JSON remains untouched for the reference lane. EMEL model conversion injects the separate `tools/bench/personaplex-inference.json` contract, keeping prompt tokens, public diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index f4e5b47b..3e07a826 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -3,6 +3,7 @@ #include #include +#include "emel/batch/planner/events.hpp" #include "emel/error/error.hpp" #include "emel/memory/streaming/errors.hpp" #include "emel/memory/streaming/events.hpp" @@ -12,6 +13,20 @@ namespace emel::speech::generator::action { +struct frame_plan_capture { + event::frame_ctx &ctx; + + void on_done(const emel::batch::planner::events::plan_done &ev) noexcept { + ctx.child_err = emel::error::cast(emel::batch::planner::error::none); + ctx.plan_step_size = ev.step_sizes[0]; + ctx.plan_output_count = ev.total_outputs; + } + + void on_error(const emel::batch::planner::events::plan_error &ev) noexcept { + ctx.child_err = ev.err; + } +}; + inline emel::error::type error_code(const error value) noexcept { return emel::error::cast(value); } @@ -467,13 +482,45 @@ struct effect_predict_frame { runtime_ev.ctx.child_err = 0; typename dependencies_type::predict_event request{ std::span{ctx.collaborators.model_codes}, - ctx.collaborators.prediction_workspace}; + ctx.collaborators.prediction_workspace, runtime_ev.ctx.plan_step_size, + runtime_ev.ctx.plan_output_count}; request.error_out = &runtime_ev.ctx.child_err; runtime_ev.ctx.child_accepted = ctx.collaborators.predictor.process_event(request); } }; +template +struct effect_plan_frame { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = + emel::error::cast(emel::batch::planner::error::none); + runtime_ev.ctx.plan_step_size = 0; + runtime_ev.ctx.plan_output_count = 0; + frame_plan_capture capture{runtime_ev.ctx}; + const auto on_done = + emel::callback:: + template from( + &capture); + const auto on_error = + emel::callback:: + template from( + &capture); + const emel::batch::planner::event::plan_request request{ + .token_ids = ctx.collaborators.model_codes.data(), + .n_tokens = ctx.collaborators.frame_plan_token_count, + .n_steps = ctx.collaborators.frame_plan_steps, + .mode = ctx.collaborators.frame_plan_mode, + .output_all = ctx.collaborators.frame_plan_output_all, + .on_done = on_done, + .on_error = on_error, + }; + runtime_ev.ctx.child_accepted = + ctx.collaborators.planner.process_event(request); + } +}; + template struct effect_sample_frame { void operator()(const runtime_event_type &runtime_ev, diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index 49354e79..f7592b72 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -2,6 +2,8 @@ #include +#include "emel/batch/planner/events.hpp" + namespace emel::speech::generator::action { namespace mode { @@ -29,6 +31,7 @@ concept duplex_dependencies = requires(dependencies_type deps) { typename dependencies_type::decode_event; deps.temporal_positions; deps.secondary_positions; + deps.planner; deps.encoder; deps.tokenizer; deps.decoder; @@ -48,6 +51,10 @@ concept duplex_dependencies = requires(dependencies_type deps) { deps.tokenizer_cache_snapshot; deps.frame_samples; deps.codebook_count; + deps.frame_plan_mode; + deps.frame_plan_steps; + deps.frame_plan_token_count; + deps.frame_plan_output_all; }; template diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp index 24b3102f..0dd15c53 100644 --- a/src/emel/speech/generator/errors.hpp +++ b/src/emel/speech/generator/errors.hpp @@ -29,6 +29,7 @@ enum class error : emel::error::type { tokenizer_initialize_failed = (1u << 22), tokenize_failed = (1u << 23), detokenize_failed = (1u << 24), + planning_failed = (1u << 25), }; } // namespace emel::speech::generator diff --git a/src/emel/speech/generator/events.hpp b/src/emel/speech/generator/events.hpp index 6a019a44..3d400efb 100644 --- a/src/emel/speech/generator/events.hpp +++ b/src/emel/speech/generator/events.hpp @@ -152,6 +152,8 @@ struct frame_ctx { int32_t tokenizer_err = 0; int32_t predicted_text_token = -1; int32_t text_token = -1; + int32_t plan_step_size = 0; + int32_t plan_output_count = 0; }; struct flush_ctx : frame_ctx {}; diff --git a/src/emel/speech/generator/guards.hpp b/src/emel/speech/generator/guards.hpp index 92a746d6..add259da 100644 --- a/src/emel/speech/generator/guards.hpp +++ b/src/emel/speech/generator/guards.hpp @@ -17,7 +17,11 @@ template struct guard_initialize_request_valid { ctx.collaborators.frame_samples > 0 && ctx.collaborators.input_codes.size() == count && ctx.collaborators.output_codes.size() == count && - ctx.collaborators.silence_pcm.size() == samples; + ctx.collaborators.silence_pcm.size() == samples && + ctx.collaborators.frame_plan_token_count > 0 && + ctx.collaborators.frame_plan_steps > 0 && + static_cast(ctx.collaborators.frame_plan_token_count) <= + ctx.collaborators.model_codes.size(); } }; diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index a18be272..50bc08a6 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -52,6 +52,7 @@ struct state_generate_done_channel_decision {}; struct state_stream_encode_result {}; struct state_stream_tokenize_result {}; +struct state_stream_plan_result {}; struct state_stream_predict_result {}; struct state_stream_sample_result {}; struct state_stream_detokenize_result {}; @@ -62,6 +63,7 @@ struct state_stream_error_channel_decision {}; struct state_flushing {}; struct state_flush_encode_result {}; struct state_flush_tokenize_result {}; +struct state_flush_plan_result {}; struct state_flush_predict_result {}; struct state_flush_sample_result {}; struct state_flush_detokenize_result {}; @@ -331,7 +333,7 @@ template struct duplex_model { + sml::completion [ generate_error_absent{} ] //------------------------------------------------------------------------------// - // Duplex encode -> tokenize -> predict -> sample -> detokenize -> decode. + // Duplex encode -> tokenize -> plan -> predict -> sample -> detokenize -> decode. , sml::state <= sml::state + sml::event [ guard::guard_stream_request_valid{} ] / action::effect_encode_stream_frame{} @@ -345,13 +347,20 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_stream_frame{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_predict_frame{} + / action::effect_plan_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_predict_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_stream_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] / action::effect_sample_frame{} @@ -417,13 +426,20 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_flush{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_child_succeeded{} ] - / action::effect_predict_frame{} + / action::effect_plan_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ guard::guard_child_succeeded{} ] + / action::effect_predict_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_child_failed{} ] + / action::effect_fail_flush{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] / action::effect_sample_frame{} diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index 33ac4317..7a79a1e4 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -197,19 +197,17 @@ struct effect_allocate_sequence { }; struct effect_allocate_step_slot { - template - void operator()(const runtime_event_type &runtime_ev, + void operator()(const event::predict_run &runtime_ev, context &ctx) const noexcept { - const auto &ev = detail::unwrap_runtime_event(runtime_ev); - ev.ctx.memory_error = static_cast( + runtime_ev.ctx.memory_error = static_cast( emel::error::cast(emel::memory::hybrid::error::none)); - ev.ctx.memory_block_count = 0; - ev.ctx.memory_accepted = + runtime_ev.ctx.memory_block_count = 0; + runtime_ev.ctx.memory_accepted = ctx.memory.process_event(emel::memory::event::allocate_slots{ .seq_id = ctx.session.sequence_id, - .token_count = 1, - .block_count_out = &ev.ctx.memory_block_count, - .error_out = &ev.ctx.memory_error, + .token_count = runtime_ev.request.planned_step_size, + .block_count_out = &runtime_ev.ctx.memory_block_count, + .error_out = &runtime_ev.ctx.memory_error, .copy_block = nullptr, .copy_block_user_data = nullptr, }); diff --git a/src/emel/speech/predictor/moshi/context.hpp b/src/emel/speech/predictor/moshi/context.hpp index ddfbd0d5..0d9b28b5 100644 --- a/src/emel/speech/predictor/moshi/context.hpp +++ b/src/emel/speech/predictor/moshi/context.hpp @@ -18,6 +18,8 @@ inline constexpr int32_t k_max_delay_rows = 128; struct policies { int32_t token_zero = 0; int32_t token_ungenerated = 0; + int32_t prediction_step_size = 0; + int32_t prediction_output_count = 0; }; struct lmgen_state { diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 4c58ad43..029920af 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -109,12 +109,17 @@ struct predict { emel::memory::view::snapshot memory = {}; }; - predict(std::span model_tokens_ref, - workspace &workspace_ref) noexcept - : model_tokens(model_tokens_ref), prediction_workspace(workspace_ref) {} + predict(std::span model_tokens_ref, workspace &workspace_ref, + const int32_t planned_step_size_ref, + const int32_t planned_output_count_ref) noexcept + : model_tokens(model_tokens_ref), prediction_workspace(workspace_ref), + planned_step_size(planned_step_size_ref), + planned_output_count(planned_output_count_ref) {} std::span model_tokens = {}; workspace &prediction_workspace; + int32_t planned_step_size = 0; + int32_t planned_output_count = 0; emel::error::type *error_out = nullptr; }; diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 0dc15891..d41faf19 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -50,7 +50,9 @@ struct guard_bind_contract_valid { runtime_ev.request.delay_cache_row_capacity >= row_count && runtime_ev.request.delay_cache_row_capacity <= action::k_max_delay_rows && - ctx.policy.token_ungenerated < ctx.policy.token_zero; + ctx.policy.token_ungenerated < ctx.policy.token_zero && + ctx.policy.prediction_step_size > 0 && + ctx.policy.prediction_output_count > 0; } }; @@ -162,7 +164,11 @@ struct guard_predict_request_valid { !ctx.voice.loaded || (ctx.voice.ready && ctx.voice.prompt_ready); return ctx.session.model != nullptr && voice_ready && runtime_ev.request.model_tokens.size() == - static_cast(ctx.lmgen.codebook_count); + static_cast(ctx.lmgen.codebook_count) && + runtime_ev.request.planned_step_size == + ctx.policy.prediction_step_size && + runtime_ev.request.planned_output_count == + ctx.policy.prediction_output_count; } }; diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index 73073b68..d740e52f 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -7,6 +7,7 @@ #include #include "../../allocation_tracker.hpp" +#include "emel/batch/planner/sm.hpp" #include "emel/error/error.hpp" #include "emel/memory/streaming/sm.hpp" #include "emel/speech/generator/sm.hpp" @@ -53,11 +54,17 @@ struct fake_prediction_workspace {}; struct fake_predict { fake_predict(std::span tokens_ref, - fake_prediction_workspace &workspace_ref) noexcept - : tokens(tokens_ref), workspace(workspace_ref) {} + fake_prediction_workspace &workspace_ref, + const int32_t planned_step_size_ref, + const int32_t planned_output_count_ref) noexcept + : tokens(tokens_ref), workspace(workspace_ref), + planned_step_size(planned_step_size_ref), + planned_output_count(planned_output_count_ref) {} std::span tokens; fake_prediction_workspace &workspace; + int32_t planned_step_size = 0; + int32_t planned_output_count = 0; emel::error::type *error_out = nullptr; }; @@ -215,6 +222,8 @@ struct fake_predictor_actor { int32_t prompt_condition_calls = 0; int32_t predict_calls = 0; int32_t sample_calls = 0; + int32_t last_plan_step_size = 0; + int32_t last_plan_output_count = 0; int32_t rejected_initialize_call = 0; bool voice_accepted = true; bool prompt_begin_accepted = true; @@ -265,6 +274,8 @@ struct fake_predictor_actor { bool process_event(const fake_predict &request) noexcept { ++predict_calls; + last_plan_step_size = request.planned_step_size; + last_plan_output_count = request.planned_output_count; *request.error_out = predict_error; return predict_accepted; } @@ -304,6 +315,7 @@ struct fake_dependencies { emel::memory::streaming::sm &temporal_positions; emel::memory::streaming::sm &secondary_positions; + emel::batch::planner::sm &planner; fake_encoder_actor &encoder; fake_tokenizer_actor &tokenizer; fake_decoder_actor &decoder; @@ -323,6 +335,11 @@ struct fake_dependencies { std::span tokenizer_cache_snapshot = {}; int32_t frame_samples = 0; int32_t codebook_count = 0; + emel::batch::planner::event::plan_mode frame_plan_mode = + emel::batch::planner::event::plan_mode::simple; + int32_t frame_plan_steps = 0; + int32_t frame_plan_token_count = 0; + bool frame_plan_output_all = false; }; struct fixture { @@ -336,6 +353,7 @@ struct fixture { emel::memory::streaming::dependencies{.capacity = 16}}; emel::memory::streaming::sm secondary_positions{ emel::memory::streaming::dependencies{.capacity = 16}}; + emel::batch::planner::sm planner{}; fake_encoder_actor encoder{}; fake_tokenizer_actor tokenizer{}; fake_decoder_actor decoder{}; @@ -345,10 +363,14 @@ struct fixture { generator::sm machine; explicit fixture(const int32_t frame_samples = 4, - const int32_t codebook_count = 2) + const int32_t codebook_count = 2, + const emel::batch::planner::event::plan_mode + frame_plan_mode = + emel::batch::planner::event::plan_mode::simple) : dependencies{ .temporal_positions = temporal_positions, .secondary_positions = secondary_positions, + .planner = planner, .encoder = encoder, .tokenizer = tokenizer, .decoder = decoder, @@ -364,6 +386,10 @@ struct fixture { .tokenizer_cache_snapshot = std::span{tokenizer_cache_snapshot}, .frame_samples = frame_samples, .codebook_count = codebook_count, + .frame_plan_mode = frame_plan_mode, + .frame_plan_steps = 1, + .frame_plan_token_count = 1, + .frame_plan_output_all = true, }, machine{dependencies} {} @@ -732,11 +758,40 @@ TEST_CASE("speech_generator_streams_through_injected_actor_pipeline") { CHECK(text_token == 42); CHECK(test->predictor.predict_calls == 1); CHECK(test->predictor.sample_calls == 1); + CHECK(test->predictor.last_plan_step_size == 1); + CHECK(test->predictor.last_plan_output_count == 1); CHECK(sample_count == 4); CHECK(produced); CHECK(pcm_out[0] == doctest::Approx(0.25f)); } +TEST_CASE("speech_generator_reports_frame_planning_failure") { + auto test = std::make_unique( + 4, 2, static_cast(99)); + advance_to_ready(*test); + std::array pcm_in{}; + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = -1; + int32_t sample_count = 0; + bool produced = false; + emel::error::type err = 0; + generator::event::stream_frame request{std::span{pcm_in}, + std::span{pcm_out}, + std::span{encoded}, + std::span{generated}, + text_token, + sample_count, + produced, + err}; + + CHECK_FALSE(test->machine.process_event(request)); + CHECK(err == + generator::action::error_code(generator::error::planning_failed)); + CHECK(test->predictor.predict_calls == 0); +} + TEST_CASE("speech_generator_streams_pending_frames_and_reports_failures") { auto test = std::make_unique(); advance_to_ready(*test); diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 214e7403..5b9c8ff8 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -67,6 +67,8 @@ moshi::action::dependencies make_predictor_dependencies( moshi::action::policies{ .token_zero = -1, .token_ungenerated = -2, + .prediction_step_size = 1, + .prediction_output_count = 1, }, }; } @@ -379,7 +381,8 @@ TEST_CASE("speech_moshi_predictor_rejects_predict_before_initialize") { moshi::event::predict::workspace workspace{}; emel::error::type err = k_no_error; - moshi::event::predict predict{std::span{input}, workspace}; + moshi::event::predict predict{std::span{input}, workspace, 1, + 1}; predict.error_out = &err; CHECK_FALSE(generator.process_event(predict)); @@ -526,7 +529,7 @@ TEST_CASE( std::span{ model_tokens.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - workspace}; + workspace, 1, 1}; blocked_predict.error_out = &err; CHECK_FALSE(generator.process_event(blocked_predict)); CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); @@ -640,7 +643,7 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" moshi::event::predict blocked_predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - workspace}; + workspace, 1, 1}; blocked_predict.error_out = &err; CHECK_FALSE(generator.process_event(blocked_predict)); CHECK(err == emel::error::cast(moshi::error::voice_prompt_pending)); @@ -688,7 +691,7 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" moshi::event::predict first_predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - workspace}; + workspace, 1, 1}; first_predict.error_out = &err; REQUIRE(generator.process_event(first_predict)); moshi::event::sample first_sample{ @@ -762,7 +765,7 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" moshi::event::predict predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - workspace}; + workspace, 1, 1}; predict.error_out = &err; err = k_no_error; @@ -835,7 +838,7 @@ TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { moshi::event::predict predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - workspace}; + workspace, 1, 1}; predict.error_out = &err; REQUIRE(generator.process_event(predict)); @@ -1248,7 +1251,8 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { auto generator_snapshot = std::make_unique(); std::array generator_input = {}; moshi::event::predict generator_predict{ - std::span{generator_input.data(), 1}, generator_workspace}; + std::span{generator_input.data(), 1}, generator_workspace, + 1, 1}; moshi::event::predict_run generator_predict_run{generator_predict, generator_predict_ctx}; moshi::action::effect_mark_not_initialized{}( @@ -2171,7 +2175,7 @@ TEST_CASE( moshi::event::predict predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - workspace}; + workspace, 1, 1}; predict.error_out = &err; REQUIRE(generator.process_event(predict)); moshi::event::sample sample{ diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index dc190be1..29ab8dd9 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -13,6 +13,7 @@ #include #include +#include "emel/batch/planner/sm.hpp" #include "emel/error/error.hpp" #include "emel/gguf/loader/detail.hpp" #include "emel/gguf/loader/events.hpp" @@ -95,6 +96,7 @@ struct personaplex_dependencies { emel::memory::streaming::sm &temporal_positions; emel::memory::streaming::sm &secondary_positions; + emel::batch::planner::sm &planner; mimi::sm &encoder; tokenizer::sm &tokenizer; mimi::sm &decoder; @@ -114,6 +116,11 @@ struct personaplex_dependencies { std::span tokenizer_cache_snapshot = {}; int32_t frame_samples = 0; int32_t codebook_count = 0; + emel::batch::planner::event::plan_mode frame_plan_mode = + emel::batch::planner::event::plan_mode::simple; + int32_t frame_plan_steps = 0; + int32_t frame_plan_token_count = 0; + bool frame_plan_output_all = false; }; bool read_binary_file(const std::filesystem::path &path, @@ -557,6 +564,8 @@ int main(int argc, char **argv) { predictor::policies{ .token_zero = -1, .token_ungenerated = -2, + .prediction_step_size = 1, + .prediction_output_count = 1, }, }}; predictor::event::predict::workspace prediction_workspace{}; @@ -576,6 +585,7 @@ int main(int argc, char **argv) { }}; mimi::sm encoder{}; mimi::sm decoder{}; + emel::batch::planner::sm frame_planner{}; predictor::event::initialize predictor_initialize{*lm_model.model}; predictor_initialize.max_sequences = 1; @@ -595,6 +605,7 @@ int main(int argc, char **argv) { personaplex_dependencies dependencies{ .temporal_positions = temporal_positions, .secondary_positions = secondary_positions, + .planner = frame_planner, .encoder = encoder, .tokenizer = token_delay, .decoder = decoder, @@ -625,6 +636,10 @@ int main(int argc, char **argv) { .tokenizer_cache_snapshot = std::span{tokenizer_cache_snapshot}, .frame_samples = frame_samples_i32, .codebook_count = public_n_q, + .frame_plan_mode = emel::batch::planner::event::plan_mode::simple, + .frame_plan_steps = 1, + .frame_plan_token_count = 1, + .frame_plan_output_all = true, }; generator::sm session{dependencies}; emel::error::type session_err = emel::error::cast(generator::error::none); From 4a9a0fb23a18b01a7412e96ab3edc5fcb83a869d Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 00:39:44 -0500 Subject: [PATCH 35/61] refactor: split speech graph and sample phases --- docs/benchmarking.md | 4 +- src/emel/speech/generator/actions.hpp | 18 ++- src/emel/speech/generator/context.hpp | 2 + src/emel/speech/generator/errors.hpp | 1 + src/emel/speech/generator/sm.hpp | 26 +++- src/emel/speech/predictor/moshi/actions.hpp | 49 +++++-- src/emel/speech/predictor/moshi/events.hpp | 29 +++- src/emel/speech/predictor/moshi/guards.hpp | 20 ++- src/emel/speech/predictor/moshi/sm.hpp | 137 +++++++++++++----- tests/speech/generator/lifecycle_tests.cpp | 51 +++++-- .../predictor/moshi_lifecycle_tests.cpp | 87 +++++++---- .../bench/speech/personaplex_emel_runner.cpp | 3 + 12 files changed, 328 insertions(+), 99 deletions(-) diff --git a/docs/benchmarking.md b/docs/benchmarking.md index 8c3f7e7e..42beb9b1 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -390,7 +390,9 @@ the comparison builds two isolated Release executables. `personaplex_emel_runner and drives the maintained generic speech generator with injected Mimi, batch-planner, tokenizer, Moshi predictor, sampler, streaming-memory, and decoder actors. Each streamed or flushed frame is planned through the shared batch planner before prediction; the typed one-frame plan is validated -by the predictor before memory allocation and graph execution. `moshi_reference_driver +by the predictor before memory allocation. The generic generator then dispatches graph execution +and sampled-result publication as distinct injected actor phases; the Moshi predictor enforces the +typed `prediction_ready -> execution_ready -> session_ready` protocol. `moshi_reference_driver personaplex` links only the pinned moshi.cpp/ggml reference lane. the reference configure hard-disables Metal and the script injects `--threads 1`, seed `1234`, 125 frames, temperatures, and sampling limits; there are no process-global EMEL sampling defaults. diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index 3e07a826..ec9ca468 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -521,6 +521,22 @@ struct effect_plan_frame { } }; +template +struct effect_execute_prediction_graph { + void operator()(const runtime_event_type &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.child_err = 0; + runtime_ev.ctx.graph_err = 0; + typename dependencies_type::graph_event request{ + ctx.collaborators.prediction_workspace, + std::span{ctx.collaborators.model_codes}}; + request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; + runtime_ev.ctx.child_accepted = + ctx.collaborators.graph.process_event(request); + } +}; + template struct effect_sample_frame { void operator()(const runtime_event_type &runtime_ev, @@ -532,10 +548,8 @@ struct effect_sample_frame { ctx.collaborators.predicted_codes.end(), -1); typename dependencies_type::sample_event request{ ctx.collaborators.prediction_workspace, - std::span{ctx.collaborators.model_codes}, ctx.collaborators.predicted_codes, runtime_ev.ctx.predicted_text_token}; request.error_out = &runtime_ev.ctx.child_err; - request.graph_error_out = &runtime_ev.ctx.graph_err; runtime_ev.ctx.child_accepted = ctx.collaborators.sampler.process_event(request); } diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index f7592b72..5242aa3f 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -24,6 +24,7 @@ concept duplex_dependencies = requires(dependencies_type deps) { typename dependencies_type::tokenizer_initialize_event; typename dependencies_type::tokenize_event; typename dependencies_type::predict_event; + typename dependencies_type::graph_event; typename dependencies_type::sample_event; typename dependencies_type::detokenize_event; typename dependencies_type::capture_tokenizer_state_event; @@ -36,6 +37,7 @@ concept duplex_dependencies = requires(dependencies_type deps) { deps.tokenizer; deps.decoder; deps.predictor; + deps.graph; deps.sampler; deps.prediction_workspace; deps.encoder_initialize; diff --git a/src/emel/speech/generator/errors.hpp b/src/emel/speech/generator/errors.hpp index 0dd15c53..9328a93f 100644 --- a/src/emel/speech/generator/errors.hpp +++ b/src/emel/speech/generator/errors.hpp @@ -30,6 +30,7 @@ enum class error : emel::error::type { tokenize_failed = (1u << 23), detokenize_failed = (1u << 24), planning_failed = (1u << 25), + graph_failed = (1u << 26), }; } // namespace emel::speech::generator diff --git a/src/emel/speech/generator/sm.hpp b/src/emel/speech/generator/sm.hpp index 50bc08a6..f872ab57 100644 --- a/src/emel/speech/generator/sm.hpp +++ b/src/emel/speech/generator/sm.hpp @@ -54,6 +54,7 @@ struct state_stream_encode_result {}; struct state_stream_tokenize_result {}; struct state_stream_plan_result {}; struct state_stream_predict_result {}; +struct state_stream_graph_result {}; struct state_stream_sample_result {}; struct state_stream_detokenize_result {}; struct state_stream_decode_result {}; @@ -65,6 +66,7 @@ struct state_flush_encode_result {}; struct state_flush_tokenize_result {}; struct state_flush_plan_result {}; struct state_flush_predict_result {}; +struct state_flush_graph_result {}; struct state_flush_sample_result {}; struct state_flush_detokenize_result {}; struct state_flush_decode_result {}; @@ -333,7 +335,7 @@ template struct duplex_model { + sml::completion [ generate_error_absent{} ] //------------------------------------------------------------------------------// - // Duplex encode -> tokenize -> plan -> predict -> sample -> detokenize -> decode. + // Duplex encode -> tokenize -> plan -> predict -> graph -> sample -> detokenize -> decode. , sml::state <= sml::state + sml::event [ guard::guard_stream_request_valid{} ] / action::effect_encode_stream_frame{} @@ -361,13 +363,20 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_stream_frame{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] - / action::effect_sample_frame{} + / action::effect_execute_prediction_graph{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_failed{} ] / action::effect_fail_stream_frame{} + , sml::state <= sml::state + + sml::completion [ guard::guard_prediction_succeeded{} ] + / action::effect_sample_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_prediction_failed{} ] + / action::effect_fail_stream_frame{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] / action::effect_detokenize_frame{} @@ -440,13 +449,20 @@ template struct duplex_model { sml::state + sml::completion [ guard::guard_child_failed{} ] / action::effect_fail_flush{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] - / action::effect_sample_frame{} + / action::effect_execute_prediction_graph{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_failed{} ] / action::effect_fail_flush{} + , sml::state <= sml::state + + sml::completion [ guard::guard_prediction_succeeded{} ] + / action::effect_sample_frame{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_prediction_failed{} ] + / action::effect_fail_flush{} , sml::state <= sml::state + sml::completion [ guard::guard_prediction_succeeded{} ] / action::effect_detokenize_frame{} diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index 7a79a1e4..e280b6d3 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -61,6 +61,16 @@ struct effect_mark_step_request_invalid { } }; +struct effect_mark_step_request_invalid_and_store { + template + void operator()(const runtime_event_type &runtime_ev, + context &) const noexcept { + const auto &ev = detail::unwrap_runtime_event(runtime_ev); + ev.ctx.err = detail_ns::to_error(error::request_shape); + *ev.request.error_out = ev.ctx.err; + } +}; + template struct effect_mark_graph_runtime_error { void operator()(const runtime_event_type &runtime_ev, context &) const noexcept { @@ -615,25 +625,31 @@ struct effect_publish_predict { } }; -struct effect_begin_sample { - void operator()(const event::sample_run &runtime_ev, +struct effect_begin_execute { + void operator()(const event::execute_run &runtime_ev, const context &) const noexcept { runtime_ev.ctx.err = detail_ns::to_error(error::none); runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); runtime_ev.ctx.graph_accepted = false; + runtime_ev.request.prediction_workspace.sampled_text_token = -1; + std::fill( + runtime_ev.request.prediction_workspace.sampled_audio_tokens.begin(), + runtime_ev.request.prediction_workspace.sampled_audio_tokens.end(), -1); } }; -template struct effect_run_sample_graph { - void operator()(const event::sample_run &runtime_ev, context &ctx, +template struct effect_run_prediction_graph { + void operator()(const event::execute_run &runtime_ev, context &ctx, graph_actor_type &graph) const noexcept { runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); event::graph_step graph_step{ *ctx.session.model, runtime_ev.request.prediction_workspace.memory, runtime_ev.request.model_tokens, - runtime_ev.request.audio_tokens_out, - runtime_ev.request.text_token_out, + std::span{ + runtime_ev.request.prediction_workspace.sampled_audio_tokens.data(), + static_cast(ctx.lmgen.generated_dep_q)}, + runtime_ev.request.prediction_workspace.sampled_text_token, }; graph_step.sequence_id = ctx.session.sequence_id; graph_step.error_out = &runtime_ev.ctx.graph_error; @@ -641,20 +657,33 @@ template struct effect_run_sample_graph { } }; -struct effect_publish_sample { - void operator()(const event::sample_run &runtime_ev, +struct effect_publish_execute { + void operator()(const event::execute_run &runtime_ev, context &) const noexcept { runtime_ev.ctx.err = detail_ns::to_error(error::none); } }; -struct effect_store_sample_graph_error_out { - void operator()(const event::sample_run &runtime_ev, +struct effect_store_execute_graph_error_out { + void operator()(const event::execute_run &runtime_ev, context &) const noexcept { *runtime_ev.request.graph_error_out = runtime_ev.ctx.graph_error; } }; +struct effect_publish_sample { + void operator()(const event::sample_run &runtime_ev, + const context &ctx) const noexcept { + std::copy_n( + runtime_ev.request.prediction_workspace.sampled_audio_tokens.begin(), + static_cast(ctx.lmgen.generated_dep_q), + runtime_ev.request.audio_tokens_out.begin()); + runtime_ev.request.text_token_out = + runtime_ev.request.prediction_workspace.sampled_text_token; + runtime_ev.ctx.err = detail_ns::to_error(error::none); + } +}; + struct effect_capture_tokenizer_state { void operator()(const event::capture_tokenizer_state &ev, const context &ctx) const noexcept { diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 029920af..d5533c37 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -107,6 +107,8 @@ struct prefill_personaplex_prompt { struct predict { struct workspace { emel::memory::view::snapshot memory = {}; + std::array sampled_audio_tokens = {}; + int32_t sampled_text_token = -1; }; predict(std::span model_tokens_ref, workspace &workspace_ref, @@ -123,21 +125,29 @@ struct predict { emel::error::type *error_out = nullptr; }; +struct execute { + execute(predict::workspace &workspace_ref, + std::span model_tokens_ref) noexcept + : prediction_workspace(workspace_ref), model_tokens(model_tokens_ref) {} + + predict::workspace &prediction_workspace; + std::span model_tokens = {}; + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; +}; + struct sample { sample(predict::workspace &workspace_ref, - std::span model_tokens_ref, std::span audio_tokens_out_ref, int32_t &text_token_out_ref) noexcept - : prediction_workspace(workspace_ref), model_tokens(model_tokens_ref), + : prediction_workspace(workspace_ref), audio_tokens_out(audio_tokens_out_ref), text_token_out(text_token_out_ref) {} predict::workspace &prediction_workspace; - std::span model_tokens = {}; std::span audio_tokens_out = {}; int32_t &text_token_out; emel::error::type *error_out = nullptr; - emel::error::type *graph_error_out = nullptr; }; struct capture_tokenizer_state { @@ -246,12 +256,16 @@ struct predict_ctx { emel::memory::view::snapshot &memory_snapshot; }; -struct sample_ctx { +struct execute_ctx { emel::error::type err = emel::error::cast(error::none); bool graph_accepted = false; emel::error::type graph_error = emel::error::cast(error::none); }; +struct sample_ctx { + emel::error::type err = emel::error::cast(error::none); +}; + struct initialize_run { const initialize &request; initialize_ctx &ctx; @@ -282,6 +296,11 @@ struct predict_run { predict_ctx &ctx; }; +struct execute_run { + const execute &request; + execute_ctx &ctx; +}; + struct sample_run { const sample &request; sample_ctx &ctx; diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index d41faf19..a4c9d86b 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -172,14 +172,28 @@ struct guard_predict_request_valid { } }; -struct guard_sample_request_valid { - bool operator()(const event::sample_run &runtime_ev, +struct guard_execute_request_valid { + bool operator()(const event::execute_run &runtime_ev, const action::context &ctx) const noexcept { const bool voice_ready = !ctx.voice.loaded || (ctx.voice.ready && ctx.voice.prompt_ready); return ctx.session.model != nullptr && voice_ready && runtime_ev.request.model_tokens.size() == - static_cast(ctx.lmgen.codebook_count) && + static_cast(ctx.lmgen.codebook_count); + } +}; + +struct guard_execute_request_invalid { + bool operator()(const event::execute_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_execute_request_valid{}(runtime_ev, ctx); + } +}; + +struct guard_sample_request_valid { + bool operator()(const event::sample_run &runtime_ev, + const action::context &ctx) const noexcept { + return ctx.session.model != nullptr && runtime_ev.request.audio_tokens_out.size() >= static_cast(ctx.lmgen.generated_dep_q); } diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 453f555e..7e83e53e 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -88,12 +88,17 @@ struct state_predict_capture_memory_decision {}; struct state_predict_begin {}; struct state_predict_error_out_decision {}; struct state_predict_failed_error_out_decision {}; +struct state_prediction_ready {}; +struct state_execute_request_decision {}; +struct state_execute_begin {}; +struct state_execute_graph_runtime_decision {}; +struct state_execute_running_graph {}; +struct state_execute_graph_error_out_decision {}; +struct state_execute_graph_result_decision {}; +struct state_execute_error_out_decision {}; +struct state_execute_failed_error_out_decision {}; +struct state_execution_ready {}; struct state_sample_request_decision {}; -struct state_sample_begin {}; -struct state_sample_graph_runtime_decision {}; -struct state_sample_running_graph {}; -struct state_sample_graph_error_out_decision {}; -struct state_sample_graph_result_decision {}; struct state_sample_error_out_decision {}; struct state_sample_failed_error_out_decision {}; struct state_uninit_voice_error_out_decision {}; @@ -114,6 +119,7 @@ template struct model { using prefill_prompt_run = event::prefill_personaplex_prompt_run; using prefill_voice_run = event::prefill_voice_run; using predict_run = event::predict_run; + using execute_run = event::execute_run; using sample_run = event::sample_run; // clang-format off @@ -451,7 +457,7 @@ template struct model { + sml::completion [ guard::guard_no_error_callback{} ] //------------------------------------------------------------------------------// - // Model-token prediction: memory and graph execution only. Delay + // Model-token prediction prepares memory for one typed graph execution. Delay // tokenization and detokenization are owned by the caller's tokenizer. , sml::state <= sml::state + sml::event @@ -485,10 +491,10 @@ template struct model { , sml::state <= sml::state + sml::completion / action::effect_publish_predict{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] / action::effect_store_error_out{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_no_error_out{} ] , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] @@ -496,45 +502,66 @@ template struct model { , sml::state <= sml::state + sml::completion [ guard::guard_no_error_out{} ] - // Model-family sampling executes only after prediction memory is prepared. - , sml::state <= sml::state + // Typed graph execution follows prediction-memory preparation. + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::completion [ guard::guard_execute_request_valid{} ] + / action::effect_begin_execute{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_execute_request_invalid{} ] + / action::effect_mark_step_request_invalid{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + / action::effect_run_prediction_graph{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_has_graph_error_out{} ] / action::effect_store_execute_graph_error_out{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_no_graph_error_out{} ] + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_accepted{} ] / action::effect_publish_execute{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_rejected{} ] + / action::effect_mark_graph_runtime_error{} + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= sml::state + + sml::completion [ guard::guard_no_error_out{} ] + + // Sample publication is a distinct typed request after graph execution. + , sml::state <= sml::state + sml::event - , sml::state <= sml::state - + sml::completion [ guard::guard_sample_request_valid{} ] - / action::effect_begin_sample{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_sample_request_valid{} ] / action::effect_publish_sample{} , sml::state <= sml::state + sml::completion [ guard::guard_sample_request_invalid{} ] / action::effect_mark_step_request_invalid{} - , sml::state <= - sml::state + sml::completion - , sml::state <= - sml::state + sml::completion - / action::effect_run_sample_graph{} - , sml::state <= - sml::state + sml::completion - , sml::state <= - sml::state + sml::completion - [ guard::guard_has_graph_error_out{} ] / action::effect_store_sample_graph_error_out{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_no_graph_error_out{} ] - , sml::state <= - sml::state + sml::completion - [ guard::guard_graph_step_accepted{} ] / action::effect_publish_sample{} - , sml::state <= - sml::state + sml::completion - [ guard::guard_graph_step_rejected{} ] - / action::effect_mark_graph_runtime_error{} , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] / action::effect_store_error_out{} , sml::state <= sml::state + sml::completion [ guard::guard_no_error_out{} ] - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] / action::effect_store_error_out{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_no_error_out{} ] // Predictor-owned prompt cache handoff into the injected tokenizer. @@ -555,6 +582,12 @@ template struct model { , sml::state <= sml::state + sml::event [ guard::guard_no_error_out{} ] / action::effect_mark_not_initialized{} + , sml::state <= sml::state + + sml::event [ guard::guard_has_error_out{} ] + / action::effect_mark_not_initialized_and_store{} + , sml::state <= sml::state + + sml::event [ guard::guard_no_error_out{} ] + / action::effect_mark_not_initialized{} , sml::state <= sml::state + sml::event [ guard::guard_has_error_out{} ] / action::effect_mark_not_initialized_and_store{} @@ -620,11 +653,38 @@ template struct model { , sml::state <= sml::state + sml::completion [ guard::guard_no_error_callback{} ] + //------------------------------------------------------------------------------// + // Known out-of-order prediction protocol requests. + , sml::state <= sml::state + + sml::event [ guard::guard_has_error_out{} ] + / action::effect_mark_step_request_invalid_and_store{} + , sml::state <= sml::state + + sml::event [ guard::guard_no_error_out{} ] + / action::effect_mark_step_request_invalid{} + , sml::state <= sml::state + + sml::event [ guard::guard_has_error_out{} ] + / action::effect_mark_step_request_invalid_and_store{} + , sml::state <= sml::state + + sml::event [ guard::guard_no_error_out{} ] + / action::effect_mark_step_request_invalid{} + , sml::state <= sml::state + + sml::event [ guard::guard_has_error_out{} ] + / action::effect_mark_step_request_invalid_and_store{} + , sml::state <= sml::state + + sml::event [ guard::guard_no_error_out{} ] + / action::effect_mark_step_request_invalid{} + //------------------------------------------------------------------------------// // Reset. , sml::state <= sml::state + sml::event / action::effect_reset_session{} + , sml::state <= sml::state + + sml::event + / action::effect_reset_session{} + , sml::state <= sml::state + + sml::event + / action::effect_reset_session{} //------------------------------------------------------------------------------// // Unexpected events. @@ -698,6 +758,13 @@ struct sm : public emel::sm, action::context> { return accepted && ctx.err == action::detail_ns::to_error(error::none); } + bool process_event(const event::execute &ev) { + event::execute_ctx ctx{}; + event::execute_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); + } + bool process_event(const event::sample &ev) { event::sample_ctx ctx{}; event::sample_run runtime_ev{ev, ctx}; diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index d740e52f..d9ae495d 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -68,20 +68,28 @@ struct fake_predict { emel::error::type *error_out = nullptr; }; +struct fake_execute { + fake_execute(fake_prediction_workspace &workspace_ref, + std::span tokens_ref) noexcept + : workspace(workspace_ref), tokens(tokens_ref) {} + + fake_prediction_workspace &workspace; + std::span tokens; + emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; +}; + struct fake_sample { fake_sample(fake_prediction_workspace &workspace_ref, - std::span tokens_ref, std::span tokens_out_ref, int32_t &text_token_out_ref) noexcept - : workspace(workspace_ref), tokens(tokens_ref), - tokens_out(tokens_out_ref), text_token_out(text_token_out_ref) {} + : workspace(workspace_ref), tokens_out(tokens_out_ref), + text_token_out(text_token_out_ref) {} fake_prediction_workspace &workspace; - std::span tokens; std::span tokens_out; int32_t &text_token_out; emel::error::type *error_out = nullptr; - emel::error::type *graph_error_out = nullptr; }; struct fake_tokenizer_initialize { @@ -221,6 +229,7 @@ struct fake_predictor_actor { int32_t prompt_begin_calls = 0; int32_t prompt_condition_calls = 0; int32_t predict_calls = 0; + int32_t execute_calls = 0; int32_t sample_calls = 0; int32_t last_plan_step_size = 0; int32_t last_plan_output_count = 0; @@ -229,6 +238,7 @@ struct fake_predictor_actor { bool prompt_begin_accepted = true; bool prompt_accepted = true; bool predict_accepted = true; + bool execute_accepted = true; bool sample_accepted = true; emel::error::type initialize_error = 0; emel::error::type voice_error = 0; @@ -237,8 +247,9 @@ struct fake_predictor_actor { emel::error::type prompt_error = 0; emel::error::type prompt_graph_error = 0; emel::error::type predict_error = 0; + emel::error::type execute_error = 0; + emel::error::type execute_graph_error = 0; emel::error::type sample_error = 0; - emel::error::type sample_graph_error = 0; bool voice_complete = true; bool prompt_complete = true; @@ -280,13 +291,19 @@ struct fake_predictor_actor { return predict_accepted; } + bool process_event(const fake_execute &request) noexcept { + ++execute_calls; + *request.error_out = execute_error; + *request.graph_error_out = execute_graph_error; + return execute_accepted; + } + bool process_event(const fake_sample &request) noexcept { ++sample_calls; - request.tokens_out[0] = request.tokens[0] + 100; - request.tokens_out[1] = request.tokens[1] + 100; + request.tokens_out[0] = 111; + request.tokens_out[1] = 112; request.text_token_out = 42; *request.error_out = sample_error; - *request.graph_error_out = sample_graph_error; return sample_accepted; } @@ -307,6 +324,7 @@ struct fake_dependencies { using tokenizer_initialize_event = fake_tokenizer_initialize; using tokenize_event = fake_tokenize; using predict_event = fake_predict; + using graph_event = fake_execute; using sample_event = fake_sample; using detokenize_event = fake_detokenize; using capture_tokenizer_state_event = fake_capture_tokenizer_state; @@ -320,6 +338,7 @@ struct fake_dependencies { fake_tokenizer_actor &tokenizer; fake_decoder_actor &decoder; fake_predictor_actor &predictor; + fake_predictor_actor &graph; fake_predictor_actor &sampler; fake_prediction_workspace &prediction_workspace; fake_initialize encoder_initialize = {}; @@ -375,6 +394,7 @@ struct fixture { .tokenizer = tokenizer, .decoder = decoder, .predictor = predictor, + .graph = predictor, .sampler = predictor, .prediction_workspace = prediction_workspace, .silence_pcm = std::span{silence}, @@ -757,6 +777,7 @@ TEST_CASE("speech_generator_streams_through_injected_actor_pipeline") { CHECK(generated == std::array{111, 112}); CHECK(text_token == 42); CHECK(test->predictor.predict_calls == 1); + CHECK(test->predictor.execute_calls == 1); CHECK(test->predictor.sample_calls == 1); CHECK(test->predictor.last_plan_step_size == 1); CHECK(test->predictor.last_plan_output_count == 1); @@ -845,8 +866,18 @@ TEST_CASE("speech_generator_streams_pending_frames_and_reports_failures") { generator::action::error_code(generator::error::encode_failed)); } + SUBCASE("graph failure") { + test->predictor.execute_graph_error = 4; + request.on_error = + decltype(request.on_error)::from(&probe); + CHECK_FALSE(test->machine.process_event(request)); + CHECK(probe.last_error == + generator::action::error_code(generator::error::graph_failed)); + } + SUBCASE("sample failure") { - test->predictor.sample_graph_error = 4; + test->predictor.sample_error = 4; request.on_error = decltype(request.on_error)::from(&probe); diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 5b9c8ff8..bb426300 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -694,16 +694,33 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" workspace, 1, 1}; first_predict.error_out = &err; REQUIRE(generator.process_event(first_predict)); - moshi::event::sample first_sample{ + CHECK(generator.is(stateforward::sml::state)); + moshi::event::execute first_execute{ workspace, std::span{ - input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}}; + first_execute.error_out = &err; + first_execute.graph_error_out = &graph_err; + REQUIRE(generator.process_event(first_execute)); + CHECK(generator.is(stateforward::sml::state)); + moshi::event::sample undersized_sample{ + workspace, + std::span{output.data(), static_cast( + fixture.model->moshi_lm.dep_q - 1)}, + text_token}; + undersized_sample.error_out = &err; + CHECK_FALSE(generator.process_event(undersized_sample)); + CHECK(err == emel::error::cast(moshi::error::request_shape)); + CHECK(generator.is(stateforward::sml::state)); + err = k_no_error; + moshi::event::sample first_sample{ + workspace, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; first_sample.error_out = &err; - first_sample.graph_error_out = &graph_err; REQUIRE(generator.process_event(first_sample)); + CHECK(generator.is(stateforward::sml::state)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); CHECK(graph.call_count == prompt_frames + 5); @@ -799,15 +816,19 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" err = k_no_error; graph_err = emel::error::cast(moshi::error::graph_runtime); REQUIRE(generator.process_event(predict)); - moshi::event::sample sample{ + moshi::event::execute execute{ workspace, std::span{ - input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}}; + execute.error_out = &err; + execute.graph_error_out = &graph_err; + REQUIRE(generator.process_event(execute)); + moshi::event::sample sample{ + workspace, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; sample.error_out = &err; - sample.graph_error_out = &graph_err; REQUIRE(generator.process_event(sample)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); @@ -831,9 +852,27 @@ TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { REQUIRE(generator.process_event(init)); std::array input = {}; - std::array output = {}; moshi::event::predict::workspace workspace{}; - int32_t text_token = -1; + moshi::event::execute premature_execute{ + workspace, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}}; + premature_execute.error_out = &err; + CHECK_FALSE(generator.process_event(premature_execute)); + CHECK(err == emel::error::cast(moshi::error::request_shape)); + + std::array premature_output = {}; + int32_t premature_text_token = -1; + err = k_no_error; + moshi::event::sample premature_sample{ + workspace, + std::span{premature_output.data(), + static_cast(fixture.model->moshi_lm.dep_q)}, + premature_text_token}; + premature_sample.error_out = &err; + CHECK_FALSE(generator.process_event(premature_sample)); + CHECK(err == emel::error::cast(moshi::error::request_shape)); + err = k_no_error; moshi::event::predict predict{ std::span{ @@ -842,16 +881,13 @@ TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { predict.error_out = &err; REQUIRE(generator.process_event(predict)); - moshi::event::sample sample{ + moshi::event::execute execute{ workspace, std::span{ - input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - std::span{output.data(), - static_cast(fixture.model->moshi_lm.dep_q)}, - text_token}; - sample.error_out = &err; + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}}; + execute.error_out = &err; - CHECK_FALSE(generator.process_event(sample)); + CHECK_FALSE(generator.process_event(execute)); CHECK(err == emel::error::cast(moshi::error::graph_runtime)); CHECK(kv.allocate_slots_count == 1); CHECK(kv.capture_view_count == 1); @@ -1224,8 +1260,9 @@ TEST_CASE("speech_moshi_generator_graph_outputs_use_explicit_transitions") { std::string::npos); CHECK(actions_source.find("effect_store_graph_debug_phase_out") == std::string::npos); - CHECK(sm_source.find("state_sample_graph_error_out_decision") != + CHECK(sm_source.find("state_execute_graph_error_out_decision") != std::string::npos); + CHECK(sm_source.find("state_sample_error_out_decision") != std::string::npos); CHECK(sm_source.find("state_graph_debug_phase_out_decision") == std::string::npos); } @@ -2168,29 +2205,23 @@ TEST_CASE( REQUIRE(generator.process_event(init)); std::array input = {}; - std::array output = {}; moshi::event::predict::workspace workspace{}; - output.fill(-1); - int32_t text_token = -1; moshi::event::predict predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, workspace, 1, 1}; predict.error_out = &err; REQUIRE(generator.process_event(predict)); - moshi::event::sample sample{ + moshi::event::execute execute{ workspace, std::span{ - input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, - std::span{output.data(), - static_cast(fixture.model->moshi_lm.dep_q)}, - text_token}; - sample.error_out = &err; + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}}; + execute.error_out = &err; - CHECK_FALSE(generator.process_event(sample)); + CHECK_FALSE(generator.process_event(execute)); CHECK(err == emel::error::cast(moshi::error::graph_runtime)); CHECK(kv.allocate_slots_count == 1); CHECK(kv.capture_view_count == 1); - CHECK(text_token == -1); - CHECK(output[0] == -1); + CHECK(workspace.sampled_text_token == -1); + CHECK(workspace.sampled_audio_tokens[0] == -1); } diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 29ab8dd9..e2c5b8d0 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -87,6 +87,7 @@ struct personaplex_dependencies { using tokenizer_initialize_event = tokenizer::event::initialize; using tokenize_event = tokenizer::event::tokenize; using predict_event = predictor::event::predict; + using graph_event = predictor::event::execute; using sample_event = predictor::event::sample; using detokenize_event = tokenizer::event::detokenize; using capture_tokenizer_state_event = @@ -101,6 +102,7 @@ struct personaplex_dependencies { tokenizer::sm &tokenizer; mimi::sm &decoder; predictor::sm &predictor; + predictor::sm &graph; predictor::sm &sampler; predictor::event::predict::workspace &prediction_workspace; mimi::event::initialize encoder_initialize; @@ -610,6 +612,7 @@ int main(int argc, char **argv) { .tokenizer = token_delay, .decoder = decoder, .predictor = token_predictor, + .graph = token_predictor, .sampler = token_predictor, .prediction_workspace = prediction_workspace, .encoder_initialize = From e4c10495af17d330a90a45d5a8c7ddca3d025964 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 01:00:35 -0500 Subject: [PATCH 36/61] refactor: run moshi sampling in sample rtc --- docs/benchmarking.md | 12 +++-- src/emel/speech/generator/actions.hpp | 2 + src/emel/speech/predictor/moshi/actions.hpp | 41 +++++++++++++++ src/emel/speech/predictor/moshi/events.hpp | 16 +++++- .../predictor/moshi/executor/actions.hpp | 31 +++++++++++ .../predictor/moshi/executor/guards.hpp | 52 ++++++++++++++++++- .../speech/predictor/moshi/executor/sm.hpp | 22 +++++++- src/emel/speech/predictor/moshi/guards.hpp | 2 + src/emel/speech/predictor/moshi/sm.hpp | 34 +++++++++++- tests/speech/generator/lifecycle_tests.cpp | 8 ++- .../moshi_executor_streaming_tests.cpp | 12 +++++ .../predictor/moshi_lifecycle_tests.cpp | 18 ++++++- .../bench/speech/personaplex_emel_runner.cpp | 4 ++ 13 files changed, 238 insertions(+), 16 deletions(-) diff --git a/docs/benchmarking.md b/docs/benchmarking.md index 42beb9b1..f67e6da4 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -391,11 +391,13 @@ and drives the maintained generic speech generator with injected Mimi, batch-pla Moshi predictor, sampler, streaming-memory, and decoder actors. Each streamed or flushed frame is planned through the shared batch planner before prediction; the typed one-frame plan is validated by the predictor before memory allocation. The generic generator then dispatches graph execution -and sampled-result publication as distinct injected actor phases; the Moshi predictor enforces the -typed `prediction_ready -> execution_ready -> session_ready` protocol. `moshi_reference_driver -personaplex` links only the pinned moshi.cpp/ggml reference lane. the reference configure -hard-disables Metal and the script injects `--threads 1`, seed `1234`, 125 frames, temperatures, -and sampling limits; there are no process-global EMEL sampling defaults. +and sampling as distinct injected actor phases; the Moshi predictor enforces the typed +`prediction_ready -> execution_ready -> session_ready` protocol. Its executor stops graph RTC +after temporal normalization in `sampling_ready`, then the sample RTC restores the injected +temporal-state buffer and performs text logits, text sampling, depformer execution, and audio +sampling. `moshi_reference_driver personaplex` links only the pinned moshi.cpp/ggml reference lane. +the reference configure hard-disables Metal and the script injects `--threads 1`, seed `1234`, 125 +frames, temperatures, and sampling limits; there are no process-global EMEL sampling defaults. the pinned upstream JSON remains untouched for the reference lane. EMEL model conversion injects the separate `tools/bench/personaplex-inference.json` contract, keeping prompt tokens, public diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index ec9ca468..10b1590e 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -548,8 +548,10 @@ struct effect_sample_frame { ctx.collaborators.predicted_codes.end(), -1); typename dependencies_type::sample_event request{ ctx.collaborators.prediction_workspace, + std::span{ctx.collaborators.model_codes}, ctx.collaborators.predicted_codes, runtime_ev.ctx.predicted_text_token}; request.error_out = &runtime_ev.ctx.child_err; + request.graph_error_out = &runtime_ev.ctx.graph_err; runtime_ev.ctx.child_accepted = ctx.collaborators.sampler.process_event(request); } diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index e280b6d3..cfae8713 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -652,6 +652,9 @@ template struct effect_run_prediction_graph { runtime_ev.request.prediction_workspace.sampled_text_token, }; graph_step.sequence_id = ctx.session.sequence_id; + graph_step.phase = event::graph_phase::prediction; + graph_step.temporal_state = + runtime_ev.request.prediction_workspace.temporal_state; graph_step.error_out = &runtime_ev.ctx.graph_error; runtime_ev.ctx.graph_accepted = graph.process_event(graph_step); } @@ -671,6 +674,44 @@ struct effect_store_execute_graph_error_out { } }; +struct effect_begin_sample { + void operator()(const event::sample_run &runtime_ev, + const context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_accepted = false; + } +}; + +template struct effect_run_sampling_graph { + void operator()(const event::sample_run &runtime_ev, context &ctx, + graph_actor_type &graph) const noexcept { + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + event::graph_step graph_step{ + *ctx.session.model, + runtime_ev.request.prediction_workspace.memory, + runtime_ev.request.model_tokens, + std::span{ + runtime_ev.request.prediction_workspace.sampled_audio_tokens.data(), + static_cast(ctx.lmgen.generated_dep_q)}, + runtime_ev.request.prediction_workspace.sampled_text_token, + }; + graph_step.sequence_id = ctx.session.sequence_id; + graph_step.phase = event::graph_phase::sampling; + graph_step.temporal_state = + runtime_ev.request.prediction_workspace.temporal_state; + graph_step.error_out = &runtime_ev.ctx.graph_error; + runtime_ev.ctx.graph_accepted = graph.process_event(graph_step); + } +}; + +struct effect_store_sample_graph_error_out { + void operator()(const event::sample_run &runtime_ev, + context &) const noexcept { + *runtime_ev.request.graph_error_out = runtime_ev.ctx.graph_error; + } +}; + struct effect_publish_sample { void operator()(const event::sample_run &runtime_ev, const context &ctx) const noexcept { diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index d5533c37..30ddd58d 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -107,6 +107,7 @@ struct prefill_personaplex_prompt { struct predict { struct workspace { emel::memory::view::snapshot memory = {}; + std::span temporal_state = {}; std::array sampled_audio_tokens = {}; int32_t sampled_text_token = -1; }; @@ -138,16 +139,19 @@ struct execute { struct sample { sample(predict::workspace &workspace_ref, + std::span model_tokens_ref, std::span audio_tokens_out_ref, int32_t &text_token_out_ref) noexcept - : prediction_workspace(workspace_ref), + : prediction_workspace(workspace_ref), model_tokens(model_tokens_ref), audio_tokens_out(audio_tokens_out_ref), text_token_out(text_token_out_ref) {} predict::workspace &prediction_workspace; + std::span model_tokens = {}; std::span audio_tokens_out = {}; int32_t &text_token_out; emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; }; struct capture_tokenizer_state { @@ -164,6 +168,12 @@ struct capture_tokenizer_state { struct reset {}; +enum class graph_phase : uint8_t { + full, + prediction, + sampling, +}; + struct graph_step { graph_step(const emel::model::data &model_ref, const emel::memory::view::snapshot &memory_snapshot_ref, @@ -178,8 +188,10 @@ struct graph_step { const emel::model::data &model; const emel::memory::view::snapshot &memory_snapshot; int32_t sequence_id = 0; + graph_phase phase = graph_phase::full; std::span input_sequence = {}; std::span input_embedding = {}; + std::span temporal_state = {}; int32_t forced_text_token = -1; std::span audio_tokens_out = {}; int32_t &text_token_out; @@ -264,6 +276,8 @@ struct execute_ctx { struct sample_ctx { emel::error::type err = emel::error::cast(error::none); + bool graph_accepted = false; + emel::error::type graph_error = emel::error::cast(error::none); }; struct initialize_run { diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 5879e26f..8a40f44e 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -974,6 +974,37 @@ struct effect_publish_temporal_out_norm { } }; +struct effect_publish_prediction_state { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + std::copy_n(runtime_ev.ctx.normalized.data(), + static_cast(ctx.session.hidden_dim), + runtime_ev.request.temporal_state.begin()); + } +}; + +struct effect_restore_prediction_state_and_bind_text_logits { + void operator()(const event::step_run &runtime_ev, + context &ctx) const noexcept { + const int32_t hidden_dim = ctx.session.hidden_dim; + std::copy_n(runtime_ev.request.temporal_state.begin(), + static_cast(hidden_dim), + runtime_ev.ctx.normalized.data()); + std::copy_n(runtime_ev.request.temporal_state.begin(), + static_cast(hidden_dim), + runtime_ev.ctx.transformer_out.data()); + const auto *text_linear = + ctx.session.contract.lm.text_output_projection.tensor; + runtime_ev.ctx.text_logits_ok = false; + runtime_ev.ctx.projection_view_bound = false; + runtime_ev.ctx.projection_view = {}; + runtime_ev.ctx.best_index = -1; + runtime_ev.ctx.best_score = 0.0f; + runtime_ev.ctx.projection_view_bound = + detail::bind_tensor_view(*text_linear, runtime_ev.ctx.projection_view); + } +}; + struct effect_bind_text_token_logits { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 02ebc69a..34d60e60 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -370,12 +370,60 @@ struct guard_step_model_mismatch { struct guard_step_shape_valid { bool operator()(const event::step_run &runtime_ev, const action::context &ctx) const noexcept { - return runtime_ev.request.input_sequence.data() != nullptr && + const bool full = runtime_ev.request.phase == + emel::speech::predictor::moshi::event::graph_phase::full; + const bool prediction = + runtime_ev.request.phase == + emel::speech::predictor::moshi::event::graph_phase::prediction; + return (full || prediction) && + runtime_ev.request.input_sequence.data() != nullptr && runtime_ev.request.input_sequence.size() == static_cast(ctx.session.codebook_count) && runtime_ev.request.audio_tokens_out.data() != nullptr && runtime_ev.request.audio_tokens_out.size() >= - static_cast(ctx.session.dep_q); + static_cast(ctx.session.dep_q) && + (full || runtime_ev.request.temporal_state.size() >= + static_cast(ctx.session.hidden_dim)); + } +}; + +struct guard_sampling_step_valid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return runtime_ev.request.phase == + emel::speech::predictor::moshi::event::graph_phase::sampling && + guard_step_model_matches{}(runtime_ev, ctx) && + runtime_ev.request.input_sequence.data() != nullptr && + runtime_ev.request.input_sequence.size() == + static_cast(ctx.session.codebook_count) && + runtime_ev.request.audio_tokens_out.data() != nullptr && + runtime_ev.request.audio_tokens_out.size() >= + static_cast(ctx.session.dep_q) && + runtime_ev.request.temporal_state.size() >= + static_cast(ctx.session.hidden_dim); + } +}; + +struct guard_sampling_step_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_sampling_step_valid{}(runtime_ev, ctx); + } +}; + +struct guard_full_graph_phase { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.phase == + emel::speech::predictor::moshi::event::graph_phase::full; + } +}; + +struct guard_prediction_graph_phase { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.phase == + emel::speech::predictor::moshi::event::graph_phase::prediction; } }; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 900a92e5..2ce95e0a 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -92,6 +92,8 @@ struct state_temporal_out_norm {}; struct state_temporal_out_norm_rms_result_decision {}; struct state_temporal_out_norm_scale {}; struct state_temporal_out_norm_result_decision {}; +struct state_text_logits_phase_decision {}; +struct state_sampling_ready {}; struct state_text_logits {}; struct state_text_logits_bind_result_decision {}; struct state_text_logits_run {}; @@ -600,12 +602,25 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_temporal_out_norm_failed{} ] / action::effect_mark_graph_execution_unsupported{} - , sml::state <= sml::state + , sml::state <= + sml::state + + sml::completion [ guard::guard_full_graph_phase{} ] + , sml::state <= + sml::state + + sml::completion [ guard::guard_prediction_graph_phase{} ] + / action::effect_publish_prediction_state{} + , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_supported{} ] / action::effect_bind_text_token_logits{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_unsupported{} ] / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::event [ guard::guard_sampling_step_valid{} ] + / action::effect_restore_prediction_state_and_bind_text_logits{} + , sml::state <= sml::state + + sml::event [ guard::guard_sampling_step_invalid{} ] + / action::effect_mark_request_shape{} , sml::state <= sml::state + sml::completion , sml::state <= sml::state @@ -1001,6 +1016,9 @@ struct model { , sml::state <= sml::state + sml::event / action::effect_reset_session{} + , sml::state <= sml::state + + sml::event + / action::effect_reset_session{} //------------------------------------------------------------------------------// // Unexpected events. diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index a4c9d86b..0ffb3524 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -194,6 +194,8 @@ struct guard_sample_request_valid { bool operator()(const event::sample_run &runtime_ev, const action::context &ctx) const noexcept { return ctx.session.model != nullptr && + runtime_ev.request.model_tokens.size() == + static_cast(ctx.lmgen.codebook_count) && runtime_ev.request.audio_tokens_out.size() >= static_cast(ctx.lmgen.generated_dep_q); } diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 7e83e53e..68fc68df 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -99,8 +99,13 @@ struct state_execute_error_out_decision {}; struct state_execute_failed_error_out_decision {}; struct state_execution_ready {}; struct state_sample_request_decision {}; +struct state_sample_begin {}; +struct state_sample_running_graph {}; +struct state_sample_graph_error_out_decision {}; +struct state_sample_graph_result_decision {}; struct state_sample_error_out_decision {}; struct state_sample_failed_error_out_decision {}; +struct state_sample_graph_failed_error_out_decision {}; struct state_uninit_voice_error_out_decision {}; struct state_uninit_voice_callback_decision {}; struct state_uninit_prefill_voice_error_out_decision {}; @@ -546,13 +551,31 @@ template struct model { // Sample publication is a distinct typed request after graph execution. , sml::state <= sml::state + sml::event - , sml::state <= + , sml::state <= sml::state + sml::completion - [ guard::guard_sample_request_valid{} ] / action::effect_publish_sample{} + [ guard::guard_sample_request_valid{} ] / action::effect_begin_sample{} , sml::state <= sml::state + sml::completion [ guard::guard_sample_request_invalid{} ] / action::effect_mark_step_request_invalid{} + , sml::state <= sml::state + + sml::completion + / action::effect_run_sampling_graph{} + , sml::state <= + sml::state + sml::completion + , sml::state <= + sml::state + sml::completion + [ guard::guard_has_graph_error_out{} ] / action::effect_store_sample_graph_error_out{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_no_graph_error_out{} ] + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_accepted{} ] / action::effect_publish_sample{} + , sml::state <= + sml::state + sml::completion + [ guard::guard_graph_step_rejected{} ] + / action::effect_mark_graph_runtime_error{} , sml::state <= sml::state + sml::completion [ guard::guard_has_error_out{} ] / action::effect_store_error_out{} @@ -563,6 +586,13 @@ template struct model { / action::effect_store_error_out{} , sml::state <= sml::state + sml::completion [ guard::guard_no_error_out{} ] + , sml::state <= + sml::state + + sml::completion [ guard::guard_has_error_out{} ] + / action::effect_store_error_out{} + , sml::state <= + sml::state + + sml::completion [ guard::guard_no_error_out{} ] // Predictor-owned prompt cache handoff into the injected tokenizer. , sml::state <= sml::state diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index d9ae495d..61960235 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -81,15 +81,18 @@ struct fake_execute { struct fake_sample { fake_sample(fake_prediction_workspace &workspace_ref, + std::span tokens_ref, std::span tokens_out_ref, int32_t &text_token_out_ref) noexcept - : workspace(workspace_ref), tokens_out(tokens_out_ref), - text_token_out(text_token_out_ref) {} + : workspace(workspace_ref), tokens(tokens_ref), + tokens_out(tokens_out_ref), text_token_out(text_token_out_ref) {} fake_prediction_workspace &workspace; + std::span tokens; std::span tokens_out; int32_t &text_token_out; emel::error::type *error_out = nullptr; + emel::error::type *graph_error_out = nullptr; }; struct fake_tokenizer_initialize { @@ -304,6 +307,7 @@ struct fake_predictor_actor { request.tokens_out[1] = 112; request.text_token_out = 42; *request.error_out = sample_error; + *request.graph_error_out = 0; return sample_accepted; } diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index 9103f4d6..8015ea52 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -128,6 +128,7 @@ TEST_CASE( std::array input = {}; std::array output = {}; + std::vector temporal_state(static_cast(lm.dim)); input.fill(-1); input[0] = lm.text_padding_id; emel::memory::view::snapshot unused_snapshot = {}; @@ -138,12 +139,23 @@ TEST_CASE( std::span{output.data(), static_cast(lm.dep_q)}, text_token}; step.error_out = &err; + step.temporal_state = temporal_state; + step.phase = moshi::event::graph_phase::prediction; REQUIRE(machine.process_event(step)); CHECK(capture(temporal_positions).logical_end == 1); + CHECK(capture(depformer_positions).logical_end == 0); + CHECK(machine.is(stateforward::sml::state)); + + step.phase = moshi::event::graph_phase::sampling; + REQUIRE(machine.process_event(step)); CHECK(capture(depformer_positions).logical_end == lm.dep_q); + CHECK(machine.is(stateforward::sml::state)); + step.phase = moshi::event::graph_phase::prediction; REQUIRE(machine.process_event(step)); CHECK(capture(temporal_positions).logical_end == 2); + step.phase = moshi::event::graph_phase::sampling; + REQUIRE(machine.process_event(step)); CHECK(capture(depformer_positions).logical_end == lm.dep_q); } diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index bb426300..4175a4d5 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -705,6 +705,8 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" CHECK(generator.is(stateforward::sml::state)); moshi::event::sample undersized_sample{ workspace, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast( fixture.model->moshi_lm.dep_q - 1)}, text_token}; @@ -715,15 +717,18 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" err = k_no_error; moshi::event::sample first_sample{ workspace, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; first_sample.error_out = &err; + first_sample.graph_error_out = &graph_err; REQUIRE(generator.process_event(first_sample)); CHECK(generator.is(stateforward::sml::state)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); - CHECK(graph.call_count == prompt_frames + 5); + CHECK(graph.call_count == prompt_frames + 6); } TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" @@ -825,14 +830,17 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" REQUIRE(generator.process_event(execute)); moshi::event::sample sample{ workspace, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, text_token}; sample.error_out = &err; + sample.graph_error_out = &graph_err; REQUIRE(generator.process_event(sample)); CHECK(err == k_no_error); CHECK(graph_err == k_no_error); - CHECK(graph.call_count == prompt_frames + personaplex_prompt_frames + 1); + CHECK(graph.call_count == prompt_frames + personaplex_prompt_frames + 2); } TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { @@ -866,6 +874,8 @@ TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { err = k_no_error; moshi::event::sample premature_sample{ workspace, + std::span{ + input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, std::span{premature_output.data(), static_cast(fixture.model->moshi_lm.dep_q)}, premature_text_token}; @@ -2205,7 +2215,11 @@ TEST_CASE( REQUIRE(generator.process_event(init)); std::array input = {}; + std::array temporal_state = + {}; moshi::event::predict::workspace workspace{}; + workspace.temporal_state = std::span{ + temporal_state.data(), static_cast(fixture.model->moshi_lm.dim)}; moshi::event::predict predict{ std::span{ input.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index e2c5b8d0..b90c3ce6 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -570,7 +570,11 @@ int main(int argc, char **argv) { .prediction_output_count = 1, }, }}; + std::vector prediction_temporal_state( + static_cast(lm_model.model->moshi_lm.dim)); predictor::event::predict::workspace prediction_workspace{}; + prediction_workspace.temporal_state = + std::span{prediction_temporal_state}; tokenizer::sm token_delay{tokenizer::dependencies{ .delays = std::span{delay_begin, delay_end}, .cache = std::span{tokenizer_storage}, From 8c10a729f90e2aa125906b476ea8f138bf332a8d Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 01:11:12 -0500 Subject: [PATCH 37/61] refactor: inject moshi hybrid memory actor --- docs/benchmarking.md | 5 +- snapshots/lint/clang_format.txt | 1 - src/emel/speech/predictor/moshi/context.hpp | 12 ++-- .../predictor/moshi_lifecycle_tests.cpp | 57 +++++++++++-------- .../bench/speech/personaplex_emel_runner.cpp | 3 +- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/docs/benchmarking.md b/docs/benchmarking.md index f67e6da4..e715ffa7 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -388,8 +388,9 @@ on macOS, the default input is generated with Samantha at 175 words per minute s the comparison builds two isolated Release executables. `personaplex_emel_runner` links only EMEL and drives the maintained generic speech generator with injected Mimi, batch-planner, tokenizer, -Moshi predictor, sampler, streaming-memory, and decoder actors. Each streamed or flushed frame is -planned through the shared batch planner before prediction; the typed one-frame plan is validated +Moshi predictor, sampler, streaming-memory, hybrid KV/recurrent-memory, and decoder actors. Each +streamed or flushed frame is planned through the shared batch planner before prediction; the typed +one-frame plan is validated by the predictor before memory allocation. The generic generator then dispatches graph execution and sampling as distinct injected actor phases; the Moshi predictor enforces the typed `prediction_ready -> execution_ready -> session_ready` protocol. Its executor stops graph RTC diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index c31b0508..c945979d 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -613,7 +613,6 @@ tests/sm/sm_external_completion_tests.cpp tests/sm/sm_policy_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp -tests/speech/predictor/moshi_lifecycle_tests.cpp tests/speech/tokenizer/whisper_tests.cpp tests/tensor/view/lifecycle_tests.cpp tests/text/conditioner/text_conditioner_tests.cpp diff --git a/src/emel/speech/predictor/moshi/context.hpp b/src/emel/speech/predictor/moshi/context.hpp index 0d9b28b5..8e1552d7 100644 --- a/src/emel/speech/predictor/moshi/context.hpp +++ b/src/emel/speech/predictor/moshi/context.hpp @@ -3,7 +3,6 @@ #include #include -#include "emel/memory/hybrid/context.hpp" #include "emel/memory/hybrid/sm.hpp" #include "emel/model/data.hpp" #include "emel/model/moshi/detail.hpp" @@ -65,21 +64,24 @@ struct voice_prompt_state { }; template struct dependencies { - emel::memory::hybrid::kv_binding kv_cache = {}; + emel::memory::hybrid::sm &memory; graph_actor_type &graph; policies policy = {}; }; struct context { - context() = default; + explicit context(emel::memory::hybrid::sm &memory_ref, + const policies policy_ref = {}) noexcept + : memory(memory_ref), policy(policy_ref) {} + template explicit context(const dependencies &deps) - : memory(deps.kv_cache), policy(deps.policy) {} + : context(deps.memory, deps.policy) {} runtime session = {}; voice_prompt_state voice = {}; lmgen_state lmgen = {}; - emel::memory::hybrid::sm memory = {}; + emel::memory::hybrid::sm &memory; const policies policy = {}; }; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 4175a4d5..60830721 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -57,11 +57,11 @@ moshi_executor::dependencies make_executor_dependencies( } template -moshi::action::dependencies make_predictor_dependencies( - graph_actor_type &graph, - const emel::memory::hybrid::kv_binding &kv_cache = {}) noexcept { +moshi::action::dependencies +make_predictor_dependencies(graph_actor_type &graph, + emel::memory::hybrid::sm &memory) noexcept { return moshi::action::dependencies{ - .kv_cache = kv_cache, + .memory = memory, .graph = graph, .policy = moshi::action::policies{ @@ -376,7 +376,8 @@ void initialize_streaming_position(memory_streaming::sm &position) { TEST_CASE("speech_moshi_predictor_rejects_predict_before_initialize") { recording_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies(graph)}; + emel::memory::hybrid::sm memory{}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; std::array input = {0, 0, 0, 0}; moshi::event::predict::workspace workspace{}; emel::error::type err = k_no_error; @@ -393,7 +394,8 @@ TEST_CASE("speech_moshi_generator_rejects_non_lm_model_contract") { auto model = std::make_unique(); model->moshi_component_id = emel::model::data::moshi_component::mimi; recording_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies(graph)}; + emel::memory::hybrid::sm memory{}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*model}; @@ -412,9 +414,9 @@ TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { emel::error::cast(emel::model::loader::error::none)); emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; recording_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies( - graph, emel::memory::hybrid::bind_kv_actor(kv))}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -437,7 +439,8 @@ TEST_CASE("speech_moshi_predictor_rejects_missing_initialize_capacity") { } recording_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies(graph)}; + emel::memory::hybrid::sm memory{}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; init.error_out = &err; @@ -453,7 +456,9 @@ TEST_CASE("speech_moshi_predictor_rejects_missing_token_policy") { } recording_graph_executor graph{}; - moshi::sm generator{moshi::action::dependencies{.graph = graph}}; + emel::memory::hybrid::sm memory{}; + moshi::sm generator{ + moshi::action::dependencies{.memory = memory, .graph = graph}}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); @@ -483,7 +488,8 @@ TEST_CASE("speech_moshi_generator_personaplex_uses_model_inference_codebooks") { moshi::event::initialize init{*model}; moshi::event::initialize_ctx init_ctx{}; moshi::event::initialize_run run{init, init_ctx}; - moshi::action::context ctx{}; + emel::memory::hybrid::sm memory{}; + moshi::action::context ctx{memory}; moshi::action::effect_bind_contract{}(run, ctx); CHECK(moshi::guard::guard_personaplex_lmgen{}(run, ctx)); @@ -504,9 +510,9 @@ TEST_CASE( } emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; recording_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies( - graph, emel::memory::hybrid::bind_kv_actor(kv))}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -564,7 +570,8 @@ TEST_CASE("speech_moshi_generator_loads_personaplex_voice_embedding_dtypes") { moshi::event::prefill_voice prefill{}; moshi::event::prefill_voice_ctx prefill_ctx{*snapshot}; moshi::event::prefill_voice_run prefill_run{prefill, prefill_ctx}; - moshi::action::context ctx{}; + emel::memory::hybrid::sm memory{}; + moshi::action::context ctx{memory}; emel::model::data::tensor_record tensor{}; std::array data = {0x3c00u, 0x4000u, 0x4200u, 0x4400u}; tensor.data = data.data(); @@ -599,9 +606,9 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" } emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; recording_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies( - graph, emel::memory::hybrid::bind_kv_actor(kv))}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -740,9 +747,9 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" } emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; recording_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies( - graph, emel::memory::hybrid::bind_kv_actor(kv))}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; @@ -850,9 +857,9 @@ TEST_CASE("speech_moshi_predictor_reports_rejected_graph_event") { } emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; rejecting_graph_executor graph{}; - moshi::sm generator{make_predictor_dependencies( - graph, emel::memory::hybrid::bind_kv_actor(kv))}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); @@ -927,8 +934,7 @@ TEST_CASE("speech_moshi_executor_rejects_missing_numeric_policy") { } emel::kernel::sm kernel{}; - moshi_executor::sm executor{ - moshi_executor::dependencies{.kernel = kernel}}; + moshi_executor::sm executor{moshi_executor::dependencies{.kernel = kernel}}; emel::error::type err = emel::error::cast(moshi_executor::error::none); moshi_executor::event::initialize init{*fixture.model}; init.error_out = &err; @@ -1283,7 +1289,8 @@ TEST_CASE("speech_moshi_generator_and_executor_cover_explicit_error_guards") { return; } - moshi::action::context generator_ctx{}; + emel::memory::hybrid::sm memory{}; + moshi::action::context generator_ctx{memory}; moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); moshi::event::initialize_ctx init_ctx{}; @@ -2203,11 +2210,11 @@ TEST_CASE( } emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; emel::kernel::sm kernel{}; moshi_executor::sm executor{make_executor_dependencies(kernel)}; - moshi::sm generator{make_predictor_dependencies( - executor, emel::memory::hybrid::bind_kv_actor(kv))}; + moshi::sm generator{make_predictor_dependencies(executor, memory)}; emel::error::type err = k_no_error; moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index b90c3ce6..f2e4fb7c 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -559,8 +559,9 @@ int main(int argc, char **argv) { std::max(config.audio_top_k, config.text_top_k)), }, }}; + emel::memory::hybrid::sm prediction_memory{}; predictor::sm token_predictor{predictor::dependencies{ - .kv_cache = emel::memory::hybrid::kv_binding{}, + .memory = prediction_memory, .graph = prediction_runtime, .policy = predictor::policies{ From e65d300477e906b0170fd03a08fc6bce63a677d6 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 01:23:13 -0500 Subject: [PATCH 38/61] test: include sortformer execution contract --- tests/diarization/sortformer/pipeline/lifecycle_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/diarization/sortformer/pipeline/lifecycle_tests.cpp b/tests/diarization/sortformer/pipeline/lifecycle_tests.cpp index 6078373f..9ce55c50 100644 --- a/tests/diarization/sortformer/pipeline/lifecycle_tests.cpp +++ b/tests/diarization/sortformer/pipeline/lifecycle_tests.cpp @@ -18,6 +18,7 @@ #include "emel/diarization/sortformer/modules/detail.hpp" #include "emel/diarization/sortformer/transformer/detail.hpp" #include "emel/model/data.hpp" +#include "emel/model/sortformer/detail.hpp" namespace { From 98e14cc840867142a44acea85befe88465da588f Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 01:51:31 -0500 Subject: [PATCH 39/61] fix: use active macos sdk for fuzz smoke --- scripts/fuzz_smoke.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/scripts/fuzz_smoke.sh b/scripts/fuzz_smoke.sh index af37deb6..707369c9 100755 --- a/scripts/fuzz_smoke.sh +++ b/scripts/fuzz_smoke.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -euo pipefail +# shellcheck source=scripts/build_jobs.sh +source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/build_jobs.sh" + for tool in cmake ninja clang clang++; do if ! command -v "$tool" >/dev/null 2>&1; then echo "error: required tool missing: $tool" >&2 @@ -48,11 +51,25 @@ else fi fuzz_cxx_flags="" fuzz_link_flags="" +fuzz_platform_flags=() fuzz_root="$(cd "$(dirname "$fuzz_cc")/.." && pwd)" if [[ -d "$fuzz_root/lib/c++" ]]; then fuzz_cxx_flags="-stdlib=libc++ -I${fuzz_root}/include/c++/v1" fuzz_link_flags="-stdlib=libc++ -L${fuzz_root}/lib/c++ -Wl,-rpath,${fuzz_root}/lib/c++ -lc++ -lc++abi" fi + +if [[ "$(uname -s)" == "Darwin" ]]; then + if ! command -v xcrun >/dev/null 2>&1; then + echo "error: xcrun is required to locate the active macOS SDK" >&2 + exit 1 + fi + fuzz_macos_sysroot="$(xcrun --sdk macosx --show-sdk-path)" + if [[ ! -d "$fuzz_macos_sysroot" ]]; then + echo "error: active macOS SDK does not exist: $fuzz_macos_sysroot" >&2 + exit 1 + fi + fuzz_platform_flags+=("-DCMAKE_OSX_SYSROOT=$fuzz_macos_sysroot") +fi if [[ "$fuzz_cc" == "clang" ]]; then if ! ls /opt/homebrew/opt/llvm/lib/clang/*/lib/darwin/libclang_rt.fuzzer_osx.a >/dev/null 2>&1 && \ ! ls /usr/local/opt/llvm/lib/clang/*/lib/darwin/libclang_rt.fuzzer_osx.a >/dev/null 2>&1; then @@ -71,10 +88,11 @@ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -G Ninja \ -DCMAKE_CXX_COMPILER="$fuzz_cxx" \ -DCMAKE_CXX_FLAGS="$fuzz_cxx_flags" \ -DCMAKE_EXE_LINKER_FLAGS="$fuzz_link_flags" \ + "${fuzz_platform_flags[@]}" \ -DEMEL_ENABLE_FUZZ=ON \ -DEMEL_ENABLE_TESTS=OFF -cmake --build "$BUILD_DIR" --parallel +cmake --build "$BUILD_DIR" --parallel "$EMEL_BUILD_JOBS" run_fuzzer() { local name="$1" From e76668b372461929a9e4e0e75402fa01e8397876 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 01:51:31 -0500 Subject: [PATCH 40/61] test: scale chunked q8 parity tolerance --- snapshots/lint/clang_format.txt | 1 - tests/text/generator/detail_tests.cpp | 84 ++++++++++++++++++--------- 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index c945979d..f6264cb7 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -628,7 +628,6 @@ tests/text/encoders/ugm_tests.cpp tests/text/encoders/wpm_tests.cpp tests/text/generator/action_guard_tests.cpp tests/text/generator/decode_wavefront/lifecycle_tests.cpp -tests/text/generator/detail_tests.cpp tests/text/generator/determinism_tests.cpp tests/text/generator/initializer/lifecycle_tests.cpp tests/text/generator/lifecycle_tests.cpp diff --git a/tests/text/generator/detail_tests.cpp b/tests/text/generator/detail_tests.cpp index bade25ab..1c7e9e2c 100644 --- a/tests/text/generator/detail_tests.cpp +++ b/tests/text/generator/detail_tests.cpp @@ -319,8 +319,8 @@ struct qwen3_runtime_fixture { add_matrix("blk.0.ffn_down.weight", 4, 4, std::vector(16, 0.0f)); add_matrix("blk.0.ffn_up.weight", 4, 4, std::vector(16, 0.0f)); model.n_tensors = tensor_index; - REQUIRE(emel::model::qwen3::detail::build_generation_contract(model, contract) == - emel::error::type{0}); + REQUIRE(emel::model::qwen3::detail::build_generation_contract( + model, contract) == emel::error::type{0}); } }; @@ -335,10 +335,10 @@ struct prepared_qwen3_backend_fixture { const auto runtime_policy = emel::text::generator::test::make_auto_runtime_policy( model_fixture.model); - ready = emel::text::generator::detail::prepare( - backend, model_fixture.contract, matmul.actor, - runtime_policy) == - emel::error::cast(emel::model::loader::error::none); + ready = + emel::text::generator::detail::prepare(backend, model_fixture.contract, + matmul.actor, runtime_policy) == + emel::error::cast(emel::model::loader::error::none); backend.bound_tokens = {0}; backend.bound_positions = {0}; backend.bound_token_count = 1; @@ -441,8 +441,8 @@ struct gemma4_runtime_fixture { add_matrix("blk.0.ffn_down.weight", 4, 4, std::vector(16, 0.0f)); add_matrix("blk.0.ffn_up.weight", 4, 4, std::vector(16, 0.0f)); model.n_tensors = tensor_index; - REQUIRE(emel::model::gemma4::detail::build_generation_contract(model, contract) == - emel::error::type{0}); + REQUIRE(emel::model::gemma4::detail::build_generation_contract( + model, contract) == emel::error::type{0}); } }; @@ -2385,8 +2385,8 @@ TEST_CASE("generator_detail_prepare_rejects_invalid_generation_contract") { emel::model::generation::contract contract = {}; emel::text::generator::runtime_policy runtime_policy = {}; - CHECK(emel::text::generator::detail::prepare( - backend, contract, matmul.actor, runtime_policy) == + CHECK(emel::text::generator::detail::prepare(backend, contract, matmul.actor, + runtime_policy) == emel::error::cast(emel::model::loader::error::model_invalid)); CHECK(backend.model == nullptr); } @@ -2407,8 +2407,8 @@ TEST_CASE("model_generation_validate_contract_rejects_incomplete_blocks") { const auto runtime_policy = emel::text::generator::test::make_auto_runtime_policy( model_fixture->model); - CHECK(emel::text::generator::detail::prepare( - backend, model_fixture->contract, matmul.actor, runtime_policy) == + CHECK(emel::text::generator::detail::prepare(backend, model_fixture->contract, + matmul.actor, runtime_policy) == emel::error::cast(emel::model::loader::error::model_invalid)); CHECK(backend.model == nullptr); } @@ -2423,10 +2423,10 @@ TEST_CASE("generator_detail_prepare_derives_kv_geometry_from_memory_contract") { model_fixture->model); // Default geometry: n_ctx=8 pads up to one 16-token block. - REQUIRE(emel::text::generator::detail::prepare( - *backend, model_fixture->contract, matmul.actor, - runtime_policy) == - emel::error::cast(emel::model::loader::error::none)); + REQUIRE( + emel::text::generator::detail::prepare(*backend, model_fixture->contract, + matmul.actor, runtime_policy) == + emel::error::cast(emel::model::loader::error::none)); CHECK(backend->kv_block_tokens == emel::memory::view::DEFAULT_BLOCK_TOKENS); CHECK(backend->kv_positions_capacity == emel::memory::view::DEFAULT_BLOCK_TOKENS); @@ -2443,10 +2443,10 @@ TEST_CASE("generator_detail_prepare_derives_kv_geometry_from_memory_contract") { // Non-positive block tokens cannot cover the context window and are // rejected through prepare's existing model_invalid validation path. - REQUIRE(emel::text::generator::detail::prepare(*backend, model_fixture->contract, - matmul.actor, runtime_policy, - 0) == - emel::error::cast(emel::model::loader::error::model_invalid)); + REQUIRE( + emel::text::generator::detail::prepare(*backend, model_fixture->contract, + matmul.actor, runtime_policy, 0) == + emel::error::cast(emel::model::loader::error::model_invalid)); // Non-divisible geometry: capacity rounds up to whole blocks. REQUIRE(emel::text::generator::detail::prepare( @@ -4098,16 +4098,30 @@ TEST_CASE("generator_detail_nonflash_chunk4_prefill_matches_scalar_q8_k_on_" REQUIRE(chunk_fixture->backend.bound_logits.size() == scalar_fixture->backend.bound_logits.size()); float max_delta = 0.0f; + float max_reference_magnitude = 0.0f; + size_t max_delta_index = 0u; for (size_t idx = 0; idx < scalar_fixture->backend.bound_logits.size(); ++idx) { - max_delta = std::max(max_delta, - std::fabs(chunk_fixture->backend.bound_logits[idx] - - scalar_fixture->backend.bound_logits[idx])); + max_reference_magnitude = + std::max(max_reference_magnitude, + std::fabs(scalar_fixture->backend.bound_logits[idx])); + const float delta = std::fabs(chunk_fixture->backend.bound_logits[idx] - + scalar_fixture->backend.bound_logits[idx]); + if (delta > max_delta) { + max_delta = delta; + max_delta_index = idx; + } CHECK(chunk_fixture->backend.bound_logits[idx] == doctest::Approx(scalar_fixture->backend.bound_logits[idx]) .epsilon(1.0e-5f)); } - CHECK(max_delta <= 1.0e-4f); + INFO("max delta index=" + << max_delta_index + << " chunk=" << chunk_fixture->backend.bound_logits[max_delta_index] + << " scalar=" << scalar_fixture->backend.bound_logits[max_delta_index]); + const float max_allowed_delta = + std::max(1.0e-4f, max_reference_magnitude * 1.0e-6f); + CHECK(max_delta <= max_allowed_delta); #endif } @@ -4170,16 +4184,30 @@ TEST_CASE("generator_detail_nonflash_chunk8_prefill_matches_scalar_q8_k_on_" REQUIRE(chunk_fixture->backend.bound_logits.size() == scalar_fixture->backend.bound_logits.size()); float max_delta = 0.0f; + float max_reference_magnitude = 0.0f; + size_t max_delta_index = 0u; for (size_t idx = 0; idx < scalar_fixture->backend.bound_logits.size(); ++idx) { - max_delta = std::max(max_delta, - std::fabs(chunk_fixture->backend.bound_logits[idx] - - scalar_fixture->backend.bound_logits[idx])); + max_reference_magnitude = + std::max(max_reference_magnitude, + std::fabs(scalar_fixture->backend.bound_logits[idx])); + const float delta = std::fabs(chunk_fixture->backend.bound_logits[idx] - + scalar_fixture->backend.bound_logits[idx]); + if (delta > max_delta) { + max_delta = delta; + max_delta_index = idx; + } CHECK(chunk_fixture->backend.bound_logits[idx] == doctest::Approx(scalar_fixture->backend.bound_logits[idx]) .epsilon(1.0e-5f)); } - CHECK(max_delta <= 1.0e-4f); + INFO("max delta index=" + << max_delta_index + << " chunk=" << chunk_fixture->backend.bound_logits[max_delta_index] + << " scalar=" << scalar_fixture->backend.bound_logits[max_delta_index]); + const float max_allowed_delta = + std::max(1.0e-4f, max_reference_magnitude * 1.0e-6f); + CHECK(max_delta <= max_allowed_delta); #endif } From 7b3c0f9b7ccaea463970488c4ecde808d30a0f4f Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 02:14:07 -0500 Subject: [PATCH 41/61] perf: stabilize decode wavefront fork join --- snapshots/lint/clang_format.txt | 1 - src/emel/text/generator/decode_wavefront/context.hpp | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index f6264cb7..0b0b3cd1 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -449,7 +449,6 @@ src/emel/text/formatter/sm.hpp src/emel/text/generator/actions.hpp src/emel/text/generator/context.hpp src/emel/text/generator/decode_wavefront/actions.hpp -src/emel/text/generator/decode_wavefront/context.hpp src/emel/text/generator/decode_wavefront/errors.hpp src/emel/text/generator/decode_wavefront/events.hpp src/emel/text/generator/decode_wavefront/guards.hpp diff --git a/src/emel/text/generator/decode_wavefront/context.hpp b/src/emel/text/generator/decode_wavefront/context.hpp index b755ffc5..d6f301ae 100644 --- a/src/emel/text/generator/decode_wavefront/context.hpp +++ b/src/emel/text/generator/decode_wavefront/context.hpp @@ -6,10 +6,10 @@ namespace emel::text::generator::decode_wavefront::action { using lane_pool = - emel::policy::thread_pool_scheduler; + emel::policy::fork_join_lane_pool; struct context { - lane_pool * pool = nullptr; + lane_pool *pool = nullptr; }; -} // namespace emel::text::generator::decode_wavefront::action +} // namespace emel::text::generator::decode_wavefront::action From 347790142afd13e17449b2b95cad73f22a0601e3 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 02:37:58 -0500 Subject: [PATCH 42/61] fix: include internal benches in full gate --- scripts/quality_gates.sh | 1 + snapshots/bench/benchmarks.txt | 2 ++ tools/bench/quality_gates_tests.cpp | 1 + 3 files changed, 4 insertions(+) diff --git a/scripts/quality_gates.sh b/scripts/quality_gates.sh index 87e95618..287711c5 100755 --- a/scripts/quality_gates.sh +++ b/scripts/quality_gates.sh @@ -1141,6 +1141,7 @@ run_benchmark_gates() { EMEL_BENCH_RUNS="$QUALITY_GATES_BENCH_RUNS" \ EMEL_BENCH_WARMUP_ITERS="$QUALITY_GATES_BENCH_WARMUP_ITERS" \ EMEL_BENCH_WARMUP_RUNS="$QUALITY_GATES_BENCH_WARMUP_RUNS" \ + EMEL_BENCH_INTERNAL=1 \ BENCH_TOLERANCE="$QUALITY_GATES_BENCH_TOLERANCE" \ "$ROOT_DIR/scripts/bench.sh" --snapshot --compare; then full_status=0 diff --git a/snapshots/bench/benchmarks.txt b/snapshots/bench/benchmarks.txt index 07ff88bb..c711e7bf 100644 --- a/snapshots/bench/benchmarks.txt +++ b/snapshots/bench/benchmarks.txt @@ -129,6 +129,8 @@ decode_wavefront/gemv_batch8 ns_per_op=10245.420 iter=100 runs=3 decode_wavefront/ggml_batch1 ns_per_op=4695.840 iter=100 runs=3 decode_wavefront/ggml_batch4 ns_per_op=7364.160 iter=100 runs=3 decode_wavefront/ggml_batch8 ns_per_op=9325.000 iter=100 runs=3 +sm_any/any ns_per_op=0.842 iter=10000 runs=9 +sm_any/direct ns_per_op=0.388 iter=10000 runs=9 sm_scheduler/busy_worker_async ns_per_op=355.000 sm_scheduler/idle_async ns_per_op=387.080 generation/preloaded_request/lfm2_5_1_2b_thinking_q4_k_m_prompt_hello_max_tokens_1/multithreaded ns_per_op=87893208.000 diff --git a/tools/bench/quality_gates_tests.cpp b/tools/bench/quality_gates_tests.cpp index 151dd4f6..d5b38931 100644 --- a/tools/bench/quality_gates_tests.cpp +++ b/tools/bench/quality_gates_tests.cpp @@ -82,6 +82,7 @@ TEST_CASE("quality gates full benchmark branch preserves failure status") { CHECK(full_branch.find("run_step_allow_fail bench_snapshot") != std::string::npos); + CHECK(full_branch.find("EMEL_BENCH_INTERNAL=1") != std::string::npos); CHECK(full_branch.find("full_status=$?") != std::string::npos); CHECK(full_branch.find("run_full_benchmark_opt_in_suites") != std::string::npos); From 627d14f0a91d77b78b7c6c85e13a5802c88a0641 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 03:14:29 -0500 Subject: [PATCH 43/61] fix: isolate strict benchmark gates --- scripts/quality_gates.sh | 5 +++++ tools/bench/quality_gates_tests.cpp | 1 + 2 files changed, 6 insertions(+) diff --git a/scripts/quality_gates.sh b/scripts/quality_gates.sh index 287711c5..b18c0194 100755 --- a/scripts/quality_gates.sh +++ b/scripts/quality_gates.sh @@ -1289,6 +1289,11 @@ run_coverage_gate() { } parallel_enabled() { + case "${EMEL_BENCH_STRICT_REGRESSION:-0}" in + 1|true|yes) + return 1 + ;; + esac case "$QUALITY_GATES_PARALLEL" in auto|always|1|true|yes) return 0 diff --git a/tools/bench/quality_gates_tests.cpp b/tools/bench/quality_gates_tests.cpp index d5b38931..1b283d16 100644 --- a/tools/bench/quality_gates_tests.cpp +++ b/tools/bench/quality_gates_tests.cpp @@ -239,6 +239,7 @@ TEST_CASE( CHECK(script.find("QUALITY_GATES_PARALLEL") != std::string::npos); CHECK(script.find("parallel_enabled()") != std::string::npos); + CHECK(script.find("EMEL_BENCH_STRICT_REGRESSION") != std::string::npos); CHECK(script.find("start_parallel_step bench_snapshot run_benchmark_gates") != std::string::npos); CHECK( From 88e3e827f1190482c6c316b4a3e42feb26e4fd8d Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 03:30:02 -0500 Subject: [PATCH 44/61] fix: prioritize parallel matmul benchmarks --- scripts/quality_gates.sh | 1 + tools/bench/quality_gates_tests.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/scripts/quality_gates.sh b/scripts/quality_gates.sh index b18c0194..c75e32e4 100755 --- a/scripts/quality_gates.sh +++ b/scripts/quality_gates.sh @@ -479,6 +479,7 @@ add_all_benchmark_suites_from_manifest() { kernel_aarch64 \ kernel_x86_64 \ batch_planner \ + parallel_matmul \ sm_any; do add_benchmark_suite_from_manifest "$priority_runner" done diff --git a/tools/bench/quality_gates_tests.cpp b/tools/bench/quality_gates_tests.cpp index 1b283d16..4207e562 100644 --- a/tools/bench/quality_gates_tests.cpp +++ b/tools/bench/quality_gates_tests.cpp @@ -519,6 +519,12 @@ TEST_CASE( std::string::npos); CHECK(helper.find("gbnf_rule_parser") != std::string::npos); CHECK(helper.find("kernel_aarch64") != std::string::npos); + const std::size_t parallel_matmul_priority = + helper.find("parallel_matmul"); + const std::size_t manifest_expansion = helper.find("while IFS= read -r line"); + REQUIRE(parallel_matmul_priority != std::string::npos); + REQUIRE(manifest_expansion != std::string::npos); + CHECK(parallel_matmul_priority < manifest_expansion); CHECK(helper.find("runner=\"\"") != std::string::npos); CHECK(helper.find("runner=*)") != std::string::npos); CHECK(helper.find("\"$runner\" == \"all\"") != std::string::npos); From 8b41ce3d9dc579c5c4a9bc123c5f6d034cada43f Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 08:29:19 -0500 Subject: [PATCH 45/61] fix PR review regressions --- docs/benchmarking.md | 4 +++ scripts/quality_gates.sh | 5 ++++ src/emel/logits/sampler/guards.hpp | 3 +- src/emel/speech/tokenizer/moshi/guards.hpp | 10 +++++-- tests/logits/sampler/pipeline_tests.cpp | 29 +++++++++++++++++++ .../tokenizer/moshi/lifecycle_tests.cpp | 18 ++++++++++++ tools/bench/quality_gates_tests.cpp | 4 +++ 7 files changed, 69 insertions(+), 4 deletions(-) diff --git a/docs/benchmarking.md b/docs/benchmarking.md index e715ffa7..4bda7403 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -385,6 +385,10 @@ scripts/bench_personaplex_compare.sh on macOS, the default input is generated with Samantha at 175 words per minute saying `Hey, I'm Gabe. How are you doing?` directly as a mono 24 kHz signed 16-bit WAV. pass `--audio /path/to/input.wav` on another Unix host or to use an existing recording. +Changed-file quality gates pass the deterministic 24 kHz tone generated by +`scripts/setup_moshi_cpp_reference.sh` explicitly through `--audio`, so the maintained lane is +portable to non-macOS hosts. Set `EMEL_QUALITY_GATES_PERSONAPLEX_AUDIO` to inject another gate +fixture. the comparison builds two isolated Release executables. `personaplex_emel_runner` links only EMEL and drives the maintained generic speech generator with injected Mimi, batch-planner, tokenizer, diff --git a/scripts/quality_gates.sh b/scripts/quality_gates.sh index c75e32e4..de92eb2e 100755 --- a/scripts/quality_gates.sh +++ b/scripts/quality_gates.sh @@ -17,6 +17,10 @@ QUALITY_GATES_BENCH_WARMUP_ITERS="${EMEL_QUALITY_GATES_BENCH_WARMUP_ITERS:-10}" QUALITY_GATES_BENCH_WARMUP_RUNS="${EMEL_QUALITY_GATES_BENCH_WARMUP_RUNS:-1}" QUALITY_GATES_BENCH_TOLERANCE="${EMEL_QUALITY_GATES_BENCH_TOLERANCE:-0.30}" QUALITY_GATES_PERSONAPLEX_FRAMES="${EMEL_QUALITY_GATES_PERSONAPLEX_FRAMES:-40}" +MOSHI_REFERENCE_ARTIFACT_DIR="${EMEL_MOSHI_REFERENCE_ARTIFACT_DIR:-$ROOT_DIR/build/moshi_reference}" +PERSONAPLEX_AUDIO_NAME="phase_moshi_440hz_24khz_mono.wav" +DEFAULT_PERSONAPLEX_AUDIO="$MOSHI_REFERENCE_ARTIFACT_DIR/$PERSONAPLEX_AUDIO_NAME" +QUALITY_GATES_PERSONAPLEX_AUDIO="${EMEL_QUALITY_GATES_PERSONAPLEX_AUDIO:-$DEFAULT_PERSONAPLEX_AUDIO}" QUALITY_GATES_GENERATION_BENCH_ITERS="${EMEL_QUALITY_GATES_GENERATION_BENCH_ITERS:-1}" QUALITY_GATES_GENERATION_BENCH_RUNS="${EMEL_QUALITY_GATES_GENERATION_BENCH_RUNS:-1}" QUALITY_GATES_GENERATION_BENCH_WARMUP_ITERS="${EMEL_QUALITY_GATES_GENERATION_BENCH_WARMUP_ITERS:-0}" @@ -1218,6 +1222,7 @@ run_benchmark_gates() { # predictor -> sampler -> detokenizer -> decoder comparison. if run_step_allow_fail "bench_snapshot_${suite}" \ "$ROOT_DIR/scripts/bench_personaplex_compare.sh" \ + --audio "$QUALITY_GATES_PERSONAPLEX_AUDIO" \ --frames "$QUALITY_GATES_PERSONAPLEX_FRAMES"; then continue else diff --git a/src/emel/logits/sampler/guards.hpp b/src/emel/logits/sampler/guards.hpp index 0fb20623..1f81f2cf 100644 --- a/src/emel/logits/sampler/guards.hpp +++ b/src/emel/logits/sampler/guards.hpp @@ -133,6 +133,7 @@ struct temperature_top_k_request_valid { bool operator()(const event::sample_temperature_top_k_runtime &ev) const noexcept { const auto &request = ev.request; + constexpr uint32_t random_modulus = 2147483647u; return request.card > 0 && request.temperature > 0.0f && request.top_k > 0 && request.top_k <= request.card && request.logits.size() >= static_cast(request.card) && @@ -140,7 +141,7 @@ struct temperature_top_k_request_valid { request.top_probabilities.size() >= static_cast(request.top_k) && request.top_indices.size() >= static_cast(request.top_k) && - request.random_state != 0u; + request.random_state % random_modulus != 0u; } }; diff --git a/src/emel/speech/tokenizer/moshi/guards.hpp b/src/emel/speech/tokenizer/moshi/guards.hpp index 2fc036ba..36607651 100644 --- a/src/emel/speech/tokenizer/moshi/guards.hpp +++ b/src/emel/speech/tokenizer/moshi/guards.hpp @@ -261,11 +261,15 @@ struct guard_past_output_delay { struct guard_output_incomplete { bool operator()(const event::detokenize_run &runtime_ev, const action::context &ctx) const noexcept { - bool incomplete = false; + bool incomplete = + runtime_ev.request.text_token_out == ctx.config.token_zero || + runtime_ev.request.text_token_out == ctx.config.token_ungenerated; for (int32_t codebook = 0; codebook < ctx.config.delayed_audio_codebooks; ++codebook) { - if (runtime_ev.request.audio_tokens_out[static_cast(codebook)] == - ctx.config.token_zero) { + const int32_t token = + runtime_ev.request.audio_tokens_out[static_cast(codebook)]; + if (token == ctx.config.token_zero || + token == ctx.config.token_ungenerated) { incomplete = true; } } diff --git a/tests/logits/sampler/pipeline_tests.cpp b/tests/logits/sampler/pipeline_tests.cpp index 849b1660..932c0345 100644 --- a/tests/logits/sampler/pipeline_tests.cpp +++ b/tests/logits/sampler/pipeline_tests.cpp @@ -391,3 +391,32 @@ TEST_CASE("sampler rejects invalid typed temperature top-k workspace") { emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == -1); } + +TEST_CASE("sampler rejects Park-Miller zero-state seeds") { + std::array logits = {1.0f, 2.0f}; + std::array sorted_indices = {}; + std::array top_probabilities = {}; + std::array top_indices = {}; + uint32_t random_state = 2147483647u; + int32_t selected = -1; + float score = 0.0f; + emel::error::type err = emel::error::cast(emel::logits::sampler::error::none); + emel::logits::sampler::event::sample_temperature_top_k request{ + logits, + 2, + 0.8f, + 1, + sorted_indices, + top_probabilities, + top_indices, + random_state, + selected, + score, + err}; + emel::logits::sampler::sm machine{}; + + CHECK_FALSE(machine.process_event(request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(selected == -1); +} diff --git a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp index 2f4de334..b6407bae 100644 --- a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp +++ b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp @@ -209,6 +209,24 @@ TEST_CASE("speech Moshi tokenizer restores column-major voice cache") { CHECK(state.model_tokens == std::array{12, 22, 200}); } +TEST_CASE("speech Moshi tokenizer does not publish restored ungenerated output") { + standard_fixture state; + REQUIRE(state.initialize()); + + std::array column_major{}; + column_major.fill(-2); + REQUIRE(state.machine.process_event(moshi::event::restore_cache{ + .column_major_cache = std::span{column_major}, + .offset = 3, + .error_out = state.err, + })); + + REQUIRE(state.tokenize()); + const std::array generated = {41, 42}; + REQUIRE(state.detokenize(40, generated)); + CHECK_FALSE(state.produced); +} + TEST_CASE("speech Moshi tokenizer advances a provided prompt frame") { standard_fixture state; REQUIRE(state.initialize()); diff --git a/tools/bench/quality_gates_tests.cpp b/tools/bench/quality_gates_tests.cpp index 4207e562..bbb23d8a 100644 --- a/tools/bench/quality_gates_tests.cpp +++ b/tools/bench/quality_gates_tests.cpp @@ -377,6 +377,10 @@ TEST_CASE("quality gates route PersonaPlex changes through end-to-end compare") std::string::npos); CHECK(script.find("QUALITY_GATES_PERSONAPLEX_FRAMES") != std::string::npos); + CHECK(script.find("QUALITY_GATES_PERSONAPLEX_AUDIO") != + std::string::npos); + CHECK(script.find("--audio \"$QUALITY_GATES_PERSONAPLEX_AUDIO\"") != + std::string::npos); } TEST_CASE("benchmark defaults stay bounded for routine quality gates") { From 4b115ab0637132b8cd1b0e13564ce70eb2b14ac7 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 09:01:31 -0500 Subject: [PATCH 46/61] fix latest PersonaPlex review findings --- snapshots/lint/clang_format.txt | 1 + src/emel/model/moshi/detail.cpp | 7 +++-- tests/model/moshi/binding_tests.cpp | 30 +++++++++++++++++++ tools/bench/personaplex_compare_tests.cpp | 3 +- .../bench/speech/personaplex_emel_runner.cpp | 6 +++- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index 0b0b3cd1..6e21e7a0 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -612,6 +612,7 @@ tests/sm/sm_external_completion_tests.cpp tests/sm/sm_policy_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp +tests/speech/tokenizer/moshi/lifecycle_tests.cpp tests/speech/tokenizer/whisper_tests.cpp tests/tensor/view/lifecycle_tests.cpp tests/text/conditioner/text_conditioner_tests.cpp diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index 37080622..4c259075 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -888,7 +888,7 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, if (written <= 0 || static_cast(written) >= sizeof(name)) { return emel::error::cast(emel::model::loader::error::model_invalid); } - (void)bind_exact_tensor( + const bool split_input_bound = bind_exact_tensor( model_data, std::string_view{name, static_cast(written)}, codebook_layer.split_input_projection); written = std::snprintf( @@ -897,9 +897,12 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, if (written <= 0 || static_cast(written) >= sizeof(name)) { return emel::error::cast(emel::model::loader::error::model_invalid); } - (void)bind_exact_tensor( + const bool fused_input_bound = bind_exact_tensor( model_data, std::string_view{name, static_cast(written)}, codebook_layer.fused_input_projection); + if (!split_input_bound && !fused_input_bound) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } written = std::snprintf( name, sizeof(name), "lm.depformer.layers.%d.self_attn.out_projs.%d.weight", block, diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index 2223204a..7c905b24 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -544,6 +544,36 @@ TEST_CASE("enriched moshi lm fixture loads hparams, vocab, and contract") { CHECK(contract.lm.linears.tensor_count == 4u); } +TEST_CASE("moshi lm contract requires every split depformer input projection") { + auto loaded = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (loaded.model == nullptr) { + return; + } + + auto model = std::make_unique(*loaded.model); + const auto hide_tensor = [&model](const std::string_view target, + const size_t changed_character) { + for (uint32_t index = 0; index < model->n_tensors; ++index) { + auto &tensor = model->tensors[index]; + const std::string_view name{ + model->name_storage.data() + tensor.name_offset, tensor.name_length}; + if (name == target) { + model->name_storage[tensor.name_offset + changed_character] = '9'; + return true; + } + } + return false; + }; + + constexpr std::string_view split_name = + "lm.depformer.layers.0.self_attn.in_projs.1.weight"; + REQUIRE(hide_tensor(split_name, split_name.find("in_projs.1") + 9u)); + constexpr std::string_view fused_name = + "lm.depformer.layers.0.self_attn.in_proj_weight"; + (void)hide_tensor(fused_name, fused_name.size() - 1u); + CHECK(moshi::validate_execution_contract(*model) != k_none); +} + TEST_CASE("enriched mimi fixture loads hparams and contract") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { diff --git a/tools/bench/personaplex_compare_tests.cpp b/tools/bench/personaplex_compare_tests.cpp index 6a86b9ea..dd4f7e62 100644 --- a/tools/bench/personaplex_compare_tests.cpp +++ b/tools/bench/personaplex_compare_tests.cpp @@ -121,8 +121,9 @@ TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { std::string::npos); CHECK(emel_source.find("#include )) { + const bool session_finished = + flush_steps == 0 + ? session.is(stateforward::sml::state) + : session.is(stateforward::sml::state); + if (!session_finished) { std::fprintf(stderr, "PersonaPlex session failed err=%d\n", static_cast(session_err)); return 1; From 92d2c3be9145d8681b82a36be284e31aba6e9893 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 09:20:00 -0500 Subject: [PATCH 47/61] fix Moshi predictor review guards --- .planning/architecture/kernel_aarch64.md | 38 +- .planning/architecture/kernel_x86_64.md | 10 +- .planning/architecture/logits_sampler.md | 28 ++ .../architecture/mermaid/kernel_aarch64.mmd | 19 +- .../architecture/mermaid/kernel_x86_64.mmd | 5 +- .../architecture/mermaid/logits_sampler.mmd | 14 + .../mermaid/speech_predictor_moshi.mmd | 195 --------- .../speech_predictor_moshi_executor.mmd | 13 +- .../mermaid/text_generator_initializer.mmd | 5 +- .../architecture/speech_predictor_moshi.md | 400 ------------------ .../speech_predictor_moshi_executor.md | 26 +- .../text_generator_initializer.md | 10 +- README.md | 3 +- docs/benchmarking.md | 2 + snapshots/lint/clang_format.txt | 4 + .../predictor/moshi/executor/actions.hpp | 5 +- .../predictor/moshi/executor/context.hpp | 1 + .../predictor/moshi/executor/guards.hpp | 14 +- .../speech/predictor/moshi/executor/sm.hpp | 16 + src/emel/speech/predictor/moshi/guards.hpp | 35 +- src/emel/speech/predictor/moshi/sm.hpp | 24 ++ .../moshi_executor_streaming_tests.cpp | 1 + .../predictor/moshi_lifecycle_tests.cpp | 97 +++++ .../bench/speech/personaplex_emel_runner.cpp | 1 + 24 files changed, 316 insertions(+), 650 deletions(-) delete mode 100644 .planning/architecture/mermaid/speech_predictor_moshi.mmd delete mode 100644 .planning/architecture/speech_predictor_moshi.md diff --git a/.planning/architecture/kernel_aarch64.md b/.planning/architecture/kernel_aarch64.md index 88f5b913..5e5822fb 100644 --- a/.planning/architecture/kernel_aarch64.md +++ b/.planning/architecture/kernel_aarch64.md @@ -86,13 +86,18 @@ stateDiagram-v2 ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8_] / exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x8_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4_] / exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_] / exec_simd_q4_vector_packed_q8_rhs_bl8_op_mul_mat_ + ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8_] / exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4_] / exec_simd_q4_vector_packed_q8_rhs_bl4_matrix_x4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_] / exec_simd_q4_vector_packed_q8_rhs_bl4_op_mul_mat_ + ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4_] / exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_q8_rhs_] / exec_simd_q4_vector_q8_rhs_op_mul_mat_ + ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_f32_rhs_] / exec_simd_q4_vector_f32_rhs_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x8_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_matrix_x8_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_op_mul_mat_ ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q6_vector_q8_argmax_prepared_i8mm_] / exec_simd_q6_vector_q8_argmax_prepared_i8mm_op_mul_mat_argmax_ + ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8_] / exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat_argmax_ + ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4_] / exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat_argmax_ ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs_] / exec_simd_q6_vector_packed_q8_rhs_op_mul_mat_argmax_ ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_op_mul_mat_argmax_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_] / exec_simd_q6_vector_prepared_q8_rhs_op_mul_mat_ @@ -150,8 +155,9 @@ stateDiagram-v2 ready --> ready : dispatch_op_soft_max [dispatch_op_soft_max__] / dispatch_op_soft_max__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ - ready --> ready : dispatch_op_rope [rope_mode_is_false___] / mark_done_op__false__ - ready --> ready : dispatch_op_rope [rope_mode_is_true___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_mode_is_0___] / mark_done_op__false__ + ready --> ready : dispatch_op_rope [rope_mode_is_2___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_timestep_is__] / mark_done_op__ ready --> ready : dispatch_op_rope [dispatch_op_rope__] / dispatch_op_rope__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ @@ -232,14 +238,15 @@ stateDiagram-v2 ready --> ready : dispatch_op_unary [abs___] / abs__ ready --> ready : dispatch_op_unary [neg___] / neg__ ready --> ready : dispatch_op_unary [relu___] / relu__ - ready --> ready : dispatch_op_unary [abs___] / abs__ - ready --> ready : dispatch_op_unary [neg___] / neg__ - ready --> ready : dispatch_op_unary [relu___] / relu__ + ready --> ready : dispatch_op_unary [silu___] / silu__ + ready --> ready : dispatch_op_unary [abs__] / abs__ + ready --> ready : dispatch_op_unary [neg__] / neg__ + ready --> ready : dispatch_op_unary [relu__] / relu__ ready --> ready : dispatch_op_unary [exp___] / exp__ ready --> ready : dispatch_op_unary [tanh___] / tanh__ ready --> ready : dispatch_op_unary [elu___] / elu__ ready --> ready : dispatch_op_unary [gelu___] / gelu__ - ready --> ready : dispatch_op_unary [silu___] / silu__ + ready --> ready : dispatch_op_unary [silu__] / silu__ ready --> ready : dispatch_op_unary [dispatch_op_unary__] / dispatch_op_unary__ ready --> ready : dispatch_op_map_custom1 [dispatch_op_map_custom1__] / dispatch_op_map_custom1__ ready --> ready : dispatch_op_map_custom1 [dispatch_op_map_custom1__] / dispatch_op_map_custom1__ @@ -344,13 +351,18 @@ stateDiagram-v2 | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x8_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x4_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_q8_rhs_bl8_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_q8_rhs_bl4_matrix_x4_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_q8_rhs_bl4_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_q8_rhs>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_q8_rhs_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q4_vector_f32_rhs>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_f32_rhs_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x8>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q6_vector_prepared_q8_rhs_i8mm_matrix_x8_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q6_vector_prepared_q8_rhs_i8mm_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat_argmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_argmax_q6_vector_q8_argmax_prepared_i8mm>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q6_vector_q8_argmax_prepared_i8mm_op_mul_mat_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat_argmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat_argmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat_argmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q6_vector_packed_q8_rhs_op_mul_mat_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat_argmax`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q6_vector_prepared_q8_rhs_i8mm_op_mul_mat_argmax>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_mul_mat`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`simd_op_mul_mat_q6_vector_prepared_q8_rhs>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exec_simd_q6_vector_prepared_q8_rhs_op_mul_mat>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | @@ -408,8 +420,9 @@ stateDiagram-v2 | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`rope_mode_is>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`mark_done_op, false>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`rope_mode_is>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`mark_done_op, true>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`rope_mode_is<0>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`mark_done_op, false>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`rope_mode_is<2>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`mark_done_op, true>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`rope_timestep_is>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`mark_done_op>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | @@ -490,14 +503,15 @@ stateDiagram-v2 | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`abs>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`abs>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`neg>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`neg>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`relu>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`relu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`abs>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`abs>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`neg>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`neg>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`relu>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`relu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`silu>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`silu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`abs>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`abs>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`neg>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`neg>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`relu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`relu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exp>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`exp>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`tanh>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`tanh>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`elu>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`elu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`gelu>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`gelu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`silu>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`silu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`silu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`silu>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_unary>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_map_custom1`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_map_custom1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_map_custom1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_map_custom1`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_map_custom1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`dispatch_op_map_custom1>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/aarch64/sm.hpp) | diff --git a/.planning/architecture/kernel_x86_64.md b/.planning/architecture/kernel_x86_64.md index 9b4b4706..879b8ff6 100644 --- a/.planning/architecture/kernel_x86_64.md +++ b/.planning/architecture/kernel_x86_64.md @@ -131,8 +131,9 @@ stateDiagram-v2 ready --> ready : dispatch_op_soft_max [dispatch_op_soft_max__] / dispatch_op_soft_max__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ - ready --> ready : dispatch_op_rope [rope_mode_is_false___] / mark_done_op__false__ - ready --> ready : dispatch_op_rope [rope_mode_is_true___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_mode_is_0___] / mark_done_op__false__ + ready --> ready : dispatch_op_rope [rope_mode_is_2___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_timestep_is__] / mark_done_op__ ready --> ready : dispatch_op_rope [dispatch_op_rope__] / dispatch_op_rope__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ @@ -369,8 +370,9 @@ stateDiagram-v2 | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_soft_max_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`rope_mode_is>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`mark_done_op, false>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | -| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`rope_mode_is>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`mark_done_op, true>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`rope_mode_is<0>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`mark_done_op, false>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`rope_mode_is<2>>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`mark_done_op, true>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`rope_timestep_is>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`mark_done_op>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope_back`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`dispatch_op_rope_back>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/kernel/x86_64/sm.hpp) | diff --git a/.planning/architecture/logits_sampler.md b/.planning/architecture/logits_sampler.md index 70248226..c887550c 100644 --- a/.planning/architecture/logits_sampler.md +++ b/.planning/architecture/logits_sampler.md @@ -27,12 +27,21 @@ stateDiagram-v2 sample_call_decision --> errored : completion_sample_logits_runtime_ [sampler_call_failed_] / mark_sampler_error_ sample_complete_decision --> done : completion_sample_logits_runtime_ [selected_token_valid_] / none sample_complete_decision --> errored : completion_sample_logits_runtime_ [selected_token_missing_or_invalid_] / mark_invalid_request_ + ready --> state_temperature_top_k_request_decision : sample_temperature_top_k_runtime [always] / none + state_temperature_top_k_request_decision --> state_temperature_top_k_scale : completion_sample_temperature_top_k_runtime_ [temperature_top_k_request_valid_] / scale_temperature_logits_ + state_temperature_top_k_request_decision --> errored : completion_sample_temperature_top_k_runtime_ [temperature_top_k_request_invalid_] / mark_invalid_request_ + state_temperature_top_k_scale --> state_temperature_top_k_probabilities : completion_sample_temperature_top_k_runtime_ [always] / compute_temperature_probabilities_ + state_temperature_top_k_probabilities --> state_temperature_top_k_rank : completion_sample_temperature_top_k_runtime_ [always] / compute_temperature_top_k_ + state_temperature_top_k_rank --> state_temperature_top_k_select : completion_sample_temperature_top_k_runtime_ [always] / select_temperature_top_k_ + state_temperature_top_k_select --> done : completion_sample_temperature_top_k_runtime_ [always] / none done --> ready : completion_configure_runtime_ [always] / publish_done_ errored --> ready : completion_configure_runtime_ [always] / publish_error_ done --> ready : completion_sample_logits_runtime_ [always] / publish_done_ errored --> ready : completion_sample_logits_runtime_ [always] / publish_error_ done --> ready : completion_sample_preselected_runtime_ [always] / publish_done_ errored --> ready : completion_sample_preselected_runtime_ [always] / publish_error_ + done --> ready : completion_sample_temperature_top_k_runtime_ [always] / publish_done_ + errored --> ready : completion_sample_temperature_top_k_runtime_ [always] / publish_error_ ready --> ready : _ [always] / on_unexpected_ request_logits_decision --> ready : _ [always] / on_unexpected_ request_preselected_decision --> ready : _ [always] / on_unexpected_ @@ -42,6 +51,11 @@ stateDiagram-v2 sample_call --> ready : _ [always] / on_unexpected_ sample_call_decision --> ready : _ [always] / on_unexpected_ sample_complete_decision --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_request_decision --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_scale --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_probabilities --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_rank --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_select --> ready : _ [always] / on_unexpected_ done --> ready : _ [always] / on_unexpected_ errored --> ready : _ [always] / on_unexpected_ ``` @@ -69,12 +83,21 @@ stateDiagram-v2 | [`sample_call_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`sampler_call_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`mark_sampler_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`sample_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`selected_token_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`sample_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`selected_token_missing_or_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`mark_invalid_request>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`sample_temperature_top_k_runtime`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`state_temperature_top_k_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`temperature_top_k_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`scale_temperature_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`state_temperature_top_k_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`temperature_top_k_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`mark_invalid_request>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`compute_temperature_probabilities>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`state_temperature_top_k_probabilities`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_probabilities`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`compute_temperature_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`state_temperature_top_k_rank`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_rank`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`select_temperature_top_k>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`state_temperature_top_k_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`publish_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`request_logits_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`request_preselected_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | @@ -84,5 +107,10 @@ stateDiagram-v2 | [`sample_call`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`sample_call_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`sample_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_probabilities`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_rank`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | +| [`state_temperature_top_k_select`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`done`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | | [`errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`on_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | [`ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/logits/sampler/sm.hpp) | diff --git a/.planning/architecture/mermaid/kernel_aarch64.mmd b/.planning/architecture/mermaid/kernel_aarch64.mmd index e82058f0..82c43c50 100644 --- a/.planning/architecture/mermaid/kernel_aarch64.mmd +++ b/.planning/architecture/mermaid/kernel_aarch64.mmd @@ -79,13 +79,18 @@ stateDiagram-v2 ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x8_] / exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x8_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_matrix_x4_] / exec_simd_q4_vector_packed_q8_rhs_bl8_matrix_x4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl8_] / exec_simd_q4_vector_packed_q8_rhs_bl8_op_mul_mat_ + ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_f32_rhs_bl8_] / exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_matrix_x4_] / exec_simd_q4_vector_packed_q8_rhs_bl4_matrix_x4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_q8_rhs_bl4_] / exec_simd_q4_vector_packed_q8_rhs_bl4_op_mul_mat_ + ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_packed_f32_rhs_bl4_] / exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_q8_rhs_] / exec_simd_q4_vector_q8_rhs_op_mul_mat_ + ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q4_vector_f32_rhs_] / exec_simd_q4_vector_f32_rhs_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x8_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_matrix_x8_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_matrix_x4_op_mul_mat_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_i8mm_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_op_mul_mat_ ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q6_vector_q8_argmax_prepared_i8mm_] / exec_simd_q6_vector_q8_argmax_prepared_i8mm_op_mul_mat_argmax_ + ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl8_] / exec_simd_q4_vector_packed_f32_rhs_bl8_op_mul_mat_argmax_ + ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q4_vector_packed_f32_rhs_bl4_] / exec_simd_q4_vector_packed_f32_rhs_bl4_op_mul_mat_argmax_ ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q6_vector_packed_q8_rhs_] / exec_simd_q6_vector_packed_q8_rhs_op_mul_mat_argmax_ ready --> ready : dispatch_op_mul_mat_argmax [simd_op_mul_mat_argmax_q6_vector_prepared_q8_rhs_i8mm_] / exec_simd_q6_vector_prepared_q8_rhs_i8mm_op_mul_mat_argmax_ ready --> ready : dispatch_op_mul_mat [simd_op_mul_mat_q6_vector_prepared_q8_rhs_] / exec_simd_q6_vector_prepared_q8_rhs_op_mul_mat_ @@ -143,8 +148,9 @@ stateDiagram-v2 ready --> ready : dispatch_op_soft_max [dispatch_op_soft_max__] / dispatch_op_soft_max__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ - ready --> ready : dispatch_op_rope [rope_mode_is_false___] / mark_done_op__false__ - ready --> ready : dispatch_op_rope [rope_mode_is_true___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_mode_is_0___] / mark_done_op__false__ + ready --> ready : dispatch_op_rope [rope_mode_is_2___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_timestep_is__] / mark_done_op__ ready --> ready : dispatch_op_rope [dispatch_op_rope__] / dispatch_op_rope__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ @@ -225,14 +231,15 @@ stateDiagram-v2 ready --> ready : dispatch_op_unary [abs___] / abs__ ready --> ready : dispatch_op_unary [neg___] / neg__ ready --> ready : dispatch_op_unary [relu___] / relu__ - ready --> ready : dispatch_op_unary [abs___] / abs__ - ready --> ready : dispatch_op_unary [neg___] / neg__ - ready --> ready : dispatch_op_unary [relu___] / relu__ + ready --> ready : dispatch_op_unary [silu___] / silu__ + ready --> ready : dispatch_op_unary [abs__] / abs__ + ready --> ready : dispatch_op_unary [neg__] / neg__ + ready --> ready : dispatch_op_unary [relu__] / relu__ ready --> ready : dispatch_op_unary [exp___] / exp__ ready --> ready : dispatch_op_unary [tanh___] / tanh__ ready --> ready : dispatch_op_unary [elu___] / elu__ ready --> ready : dispatch_op_unary [gelu___] / gelu__ - ready --> ready : dispatch_op_unary [silu___] / silu__ + ready --> ready : dispatch_op_unary [silu__] / silu__ ready --> ready : dispatch_op_unary [dispatch_op_unary__] / dispatch_op_unary__ ready --> ready : dispatch_op_map_custom1 [dispatch_op_map_custom1__] / dispatch_op_map_custom1__ ready --> ready : dispatch_op_map_custom1 [dispatch_op_map_custom1__] / dispatch_op_map_custom1__ diff --git a/.planning/architecture/mermaid/kernel_x86_64.mmd b/.planning/architecture/mermaid/kernel_x86_64.mmd index 9f7dcc08..35568018 100644 --- a/.planning/architecture/mermaid/kernel_x86_64.mmd +++ b/.planning/architecture/mermaid/kernel_x86_64.mmd @@ -124,8 +124,9 @@ stateDiagram-v2 ready --> ready : dispatch_op_soft_max [dispatch_op_soft_max__] / dispatch_op_soft_max__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ ready --> ready : dispatch_op_soft_max_back [dispatch_op_soft_max_back__] / dispatch_op_soft_max_back__ - ready --> ready : dispatch_op_rope [rope_mode_is_false___] / mark_done_op__false__ - ready --> ready : dispatch_op_rope [rope_mode_is_true___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_mode_is_0___] / mark_done_op__false__ + ready --> ready : dispatch_op_rope [rope_mode_is_2___] / mark_done_op__true__ + ready --> ready : dispatch_op_rope [rope_timestep_is__] / mark_done_op__ ready --> ready : dispatch_op_rope [dispatch_op_rope__] / dispatch_op_rope__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ ready --> ready : dispatch_op_rope_back [dispatch_op_rope_back__] / dispatch_op_rope_back__ diff --git a/.planning/architecture/mermaid/logits_sampler.mmd b/.planning/architecture/mermaid/logits_sampler.mmd index faf1f10b..5c230682 100644 --- a/.planning/architecture/mermaid/logits_sampler.mmd +++ b/.planning/architecture/mermaid/logits_sampler.mmd @@ -20,12 +20,21 @@ stateDiagram-v2 sample_call_decision --> errored : completion_sample_logits_runtime_ [sampler_call_failed_] / mark_sampler_error_ sample_complete_decision --> done : completion_sample_logits_runtime_ [selected_token_valid_] / none sample_complete_decision --> errored : completion_sample_logits_runtime_ [selected_token_missing_or_invalid_] / mark_invalid_request_ + ready --> state_temperature_top_k_request_decision : sample_temperature_top_k_runtime [always] / none + state_temperature_top_k_request_decision --> state_temperature_top_k_scale : completion_sample_temperature_top_k_runtime_ [temperature_top_k_request_valid_] / scale_temperature_logits_ + state_temperature_top_k_request_decision --> errored : completion_sample_temperature_top_k_runtime_ [temperature_top_k_request_invalid_] / mark_invalid_request_ + state_temperature_top_k_scale --> state_temperature_top_k_probabilities : completion_sample_temperature_top_k_runtime_ [always] / compute_temperature_probabilities_ + state_temperature_top_k_probabilities --> state_temperature_top_k_rank : completion_sample_temperature_top_k_runtime_ [always] / compute_temperature_top_k_ + state_temperature_top_k_rank --> state_temperature_top_k_select : completion_sample_temperature_top_k_runtime_ [always] / select_temperature_top_k_ + state_temperature_top_k_select --> done : completion_sample_temperature_top_k_runtime_ [always] / none done --> ready : completion_configure_runtime_ [always] / publish_done_ errored --> ready : completion_configure_runtime_ [always] / publish_error_ done --> ready : completion_sample_logits_runtime_ [always] / publish_done_ errored --> ready : completion_sample_logits_runtime_ [always] / publish_error_ done --> ready : completion_sample_preselected_runtime_ [always] / publish_done_ errored --> ready : completion_sample_preselected_runtime_ [always] / publish_error_ + done --> ready : completion_sample_temperature_top_k_runtime_ [always] / publish_done_ + errored --> ready : completion_sample_temperature_top_k_runtime_ [always] / publish_error_ ready --> ready : _ [always] / on_unexpected_ request_logits_decision --> ready : _ [always] / on_unexpected_ request_preselected_decision --> ready : _ [always] / on_unexpected_ @@ -35,5 +44,10 @@ stateDiagram-v2 sample_call --> ready : _ [always] / on_unexpected_ sample_call_decision --> ready : _ [always] / on_unexpected_ sample_complete_decision --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_request_decision --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_scale --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_probabilities --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_rank --> ready : _ [always] / on_unexpected_ + state_temperature_top_k_select --> ready : _ [always] / on_unexpected_ done --> ready : _ [always] / on_unexpected_ errored --> ready : _ [always] / on_unexpected_ diff --git a/.planning/architecture/mermaid/speech_predictor_moshi.mmd b/.planning/architecture/mermaid/speech_predictor_moshi.mmd deleted file mode 100644 index f8a906ac..00000000 --- a/.planning/architecture/mermaid/speech_predictor_moshi.mmd +++ /dev/null @@ -1,195 +0,0 @@ -stateDiagram-v2 - direction TB - [*] --> state_uninitialized - state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none - state_bind_contract_decision --> state_binding : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ - state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ - state_binding --> state_lmgen_mode_decision : completion_initialize_run_ [always] / none - state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_personaplex_lmgen_] / effect_configure_personaplex_lmgen_ - state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_standard_lmgen_] / effect_configure_standard_lmgen_ - state_configure_lmgen --> state_reserve_memory : completion_initialize_run_ [always] / effect_reserve_memory_ - state_reserve_memory --> state_reserve_memory_decision : completion_initialize_run_ [always] / none - state_reserve_memory_decision --> state_allocate_sequence : completion_initialize_run_ [guard_memory_accepted_] / effect_allocate_sequence_ - state_reserve_memory_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ - state_allocate_sequence --> state_allocate_sequence_decision : completion_initialize_run_ [always] / none - state_allocate_sequence_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_memory_accepted_] / none - state_allocate_sequence_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ - state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ - state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / none - state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ - state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / none - state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_done_ - state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / none - state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ - state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / none - state_session_ready --> state_voice_request_decision : load_voice_run [always] / none - state_voice_request_decision --> state_voice_error_out_decision : completion_load_voice_run_ [guard_voice_contract_valid_] / effect_bind_voice_contract_ - state_voice_request_decision --> state_voice_failed_error_out_decision : completion_load_voice_run_ [guard_voice_contract_invalid_] / load_voice_run__ - state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ - state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none - state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ - state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / none - state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_done_ - state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none - state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ - state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none - state_session_ready --> state_prefill_voice_request_decision : prefill_voice_run [always] / none - state_prefill_voice_request_decision --> state_prefill_voice_allocate_slot : completion_prefill_voice_run_ [guard_voice_prefill_request_valid_] / effect_allocate_voice_prefill_slot_ - state_prefill_voice_request_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_prefill_request_invalid_] / prefill_voice_run__ - state_prefill_voice_allocate_slot --> state_prefill_voice_allocate_slot_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_allocate_slot_decision --> state_prefill_voice_capture_memory : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_capture_voice_prefill_memory_ - state_prefill_voice_allocate_slot_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ - state_prefill_voice_capture_memory --> state_prefill_voice_capture_memory_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_capture_memory_decision --> state_prefill_voice_begin : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_begin_voice_prefill_ - state_prefill_voice_capture_memory_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ - state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f32_] / effect_load_voice_embedding_frame_f32_ - state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f16_] / effect_load_voice_embedding_frame_f16_ - state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_bf16_] / effect_load_voice_embedding_frame_bf16_ - state_prefill_voice_embedding_frame --> state_prefill_voice_embedding_frame_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_embedding_frame_decision --> state_prefill_voice_graph_runtime_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_loaded_] / none - state_prefill_voice_embedding_frame_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_failed_] / prefill_voice_run__ - state_prefill_voice_graph_runtime_decision --> state_prefill_voice_running_graph : completion_prefill_voice_run_ [guard_graph_runtime_available_] / effect_run_voice_graph_runtime_ - state_prefill_voice_graph_runtime_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_runtime_unavailable_] / prefill_voice_run__ - state_prefill_voice_running_graph --> state_prefill_voice_graph_error_out_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ - state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_no_graph_error_out_] / none - state_prefill_voice_graph_result_decision --> state_prefill_voice_advance : completion_prefill_voice_run_ [guard_graph_step_accepted_] / effect_advance_voice_prefill_ - state_prefill_voice_graph_result_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_step_rejected_] / prefill_voice_run__ - state_prefill_voice_advance --> state_prefill_voice_complete_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_complete_] / effect_copy_voice_cache_ - state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_pending_] / none - state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_has_voice_complete_out_] / effect_store_voice_complete_out_ - state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_no_voice_complete_out_] / none - state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_has_voice_remaining_out_] / effect_store_voice_remaining_out_ - state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_no_voice_remaining_out_] / none - state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ - state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ - state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_done_ - state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ - state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_session_ready --> state_personaplex_prompt_begin_decision : begin_personaplex_prompt_run [always] / none - state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_nonempty_valid_] / effect_bind_personaplex_prompt_ - state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_empty_valid_] / effect_bind_empty_personaplex_prompt_ - state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_failed_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_invalid_] / begin_personaplex_prompt_run__ - state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ - state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ - state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_done_ - state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ - state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_session_ready --> state_prefill_personaplex_prompt_request_decision : prefill_personaplex_prompt_run [always] / none - state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_allocate_slot : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_valid_] / effect_allocate_personaplex_prompt_slot_ - state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_invalid_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_allocate_slot --> state_prefill_personaplex_prompt_allocate_slot_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_capture_memory : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_capture_personaplex_prompt_memory_ - state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_capture_memory --> state_prefill_personaplex_prompt_capture_memory_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_begin : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_begin_personaplex_prompt_prefill_ - state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_begin --> state_prefill_personaplex_prompt_phase_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pre_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_text_pending_] / effect_build_personaplex_prompt_text_frame_ - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_post_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_phase_invalid_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_frame --> state_prefill_personaplex_prompt_write_input : completion_prefill_personaplex_prompt_run_ [always] / effect_write_and_build_personaplex_prompt_input_ - state_prefill_personaplex_prompt_write_input --> state_prefill_personaplex_prompt_graph_runtime_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_running_graph : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_available_] / effect_run_personaplex_prompt_graph_runtime_ - state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_unavailable_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_running_graph --> state_prefill_personaplex_prompt_graph_error_out_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ - state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_no_graph_error_out_] / none - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_pre_silence_] / effect_advance_personaplex_prompt_pre_silence_ - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_text_] / effect_advance_personaplex_prompt_text_ - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_post_silence_] / effect_advance_personaplex_prompt_post_silence_ - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_step_rejected_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_advance --> state_prefill_personaplex_prompt_complete_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_complete_] / effect_finish_personaplex_prompt_ - state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pending_] / effect_publish_personaplex_prompt_pending_ - state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_complete_out_] / effect_store_personaplex_prompt_complete_out_ - state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_complete_out_] / none - state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_remaining_out_] / effect_store_personaplex_prompt_remaining_out_ - state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_remaining_out_] / none - state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_done_ - state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ - state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_session_ready --> state_step_request_decision : step_run [always] / none - state_step_request_decision --> state_allocate_step_slot : completion_step_run_ [guard_step_request_valid_] / effect_allocate_step_slot_ - state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_blocked_by_voice_prompt_] / effect_mark_voice_prompt_pending_ - state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_request_shape_invalid_] / effect_mark_step_request_invalid_ - state_allocate_step_slot --> state_allocate_step_slot_decision : completion_step_run_ [always] / none - state_allocate_step_slot_decision --> state_capture_memory : completion_step_run_ [guard_memory_accepted_] / effect_capture_memory_ - state_allocate_step_slot_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ - state_capture_memory --> state_capture_memory_decision : completion_step_run_ [always] / none - state_capture_memory_decision --> state_step_begin : completion_step_run_ [guard_memory_accepted_] / effect_begin_step_ - state_capture_memory_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ - state_step_begin --> state_input_write_decision : completion_step_run_ [always] / none - state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_full_input_] / effect_write_full_input_ - state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_tail_input_] / effect_write_tail_input_ - state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_no_input_write_] / none - state_build_input_sequence --> state_graph_runtime_decision : completion_step_run_ [always] / effect_build_input_sequence_ - state_graph_runtime_decision --> state_running_graph : completion_step_run_ [guard_graph_runtime_available_] / effect_run_graph_runtime_ - state_graph_runtime_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_runtime_unavailable_] / step_run__ - state_running_graph --> state_graph_error_out_decision : completion_step_run_ [always] / none - state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ - state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_no_graph_error_out_] / none - state_graph_result_decision --> state_depformer_decision : completion_step_run_ [guard_graph_step_accepted_] / none - state_graph_result_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_step_rejected_] / step_run__ - state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_replace_depformer_tokens_] / effect_replace_audio_with_zero_ - state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_use_graph_audio_tokens_] / none - state_apply_delay_mask --> state_write_generated_decision : completion_step_run_ [always] / effect_apply_delay_mask_and_advance_ - state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_should_write_generated_] / effect_write_generated_ - state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_provided_input_] / effect_write_generated_missing_ - state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_skip_pending_] / effect_consume_skip_ - state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_before_delay_] / effect_publish_no_output_ - state_skip_delay_decision --> state_collect_output : completion_step_run_ [guard_past_delay_] / effect_collect_delayed_output_ - state_collect_output --> state_output_decision : completion_step_run_ [always] / none - state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_has_ungenerated_] / effect_publish_no_output_ - state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_complete_] / effect_publish_output_ - state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_has_produced_out_] / effect_store_produced_out_ - state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_no_produced_out_] / none - state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / step_run__ - state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / none - state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / step_run__ - state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / none - state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_done_ - state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none - state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_error_ - state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none - state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / step_run__ - state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / step_run__ - state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / none - state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / effect_emit_step_error_ - state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / none - state_uninitialized --> state_uninit_voice_error_out_decision : load_voice_run [always] / load_voice_run__ - state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ - state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none - state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ - state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / none - state_uninitialized --> state_uninit_prefill_voice_error_out_decision : prefill_voice_run [always] / prefill_voice_run__ - state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ - state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ - state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_uninitialized --> state_uninit_begin_personaplex_prompt_error_out_decision : begin_personaplex_prompt_run [always] / begin_personaplex_prompt_run__ - state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ - state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ - state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_uninitialized --> state_uninit_prefill_personaplex_prompt_error_out_decision : prefill_personaplex_prompt_run [always] / prefill_personaplex_prompt_run__ - state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ - state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ - state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_session_ready --> state_uninitialized : reset_run [always] / effect_reset_session_ - state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ - state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ diff --git a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd index a5f2e0e5..2e0604d3 100644 --- a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd +++ b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd @@ -147,8 +147,12 @@ stateDiagram-v2 state_temporal_out_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ state_temporal_out_norm_scale --> state_temporal_out_norm_result_decision : completion_step_run_ [guard_temporal_out_norm_succeeded_] / effect_publish_temporal_out_norm_ state_temporal_out_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_failed_] / effect_mark_graph_execution_unsupported_ - state_temporal_out_norm_result_decision --> state_text_logits : completion_step_run_ [guard_text_logits_supported_] / effect_bind_text_token_logits_ - state_temporal_out_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm_result_decision --> state_text_logits_phase_decision : completion_step_run_ [guard_full_graph_phase_] / none + state_temporal_out_norm_result_decision --> state_sampling_ready : completion_step_run_ [guard_prediction_graph_phase_] / effect_publish_prediction_state_ + state_text_logits_phase_decision --> state_text_logits : completion_step_run_ [guard_text_logits_supported_] / effect_bind_text_token_logits_ + state_text_logits_phase_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_sampling_ready --> state_text_logits : step_run [guard_sampling_step_valid_] / effect_restore_prediction_state_and_bind_text_logits_ + state_sampling_ready --> state_step_error_out_decision : step_run [guard_sampling_step_invalid_] / effect_mark_request_shape_ state_text_logits --> state_text_logits_bind_result_decision : completion_step_run_ [always] / none state_text_logits_bind_result_decision --> state_text_logits_sample_projection : completion_step_run_ [guard_forced_text_token_valid_and_sampling_consume_] / effect_compute_text_token_logits_ state_text_logits_bind_result_decision --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_token_valid_without_sampling_consume_] / effect_publish_forced_text_token_ @@ -286,5 +290,10 @@ stateDiagram-v2 state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / step_run__ state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / none state_ready --> state_uninitialized : reset [always] / effect_reset_session_ + state_sampling_ready --> state_uninitialized : reset [always] / effect_reset_session_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ + state_ready --> state_ready : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_ready --> state_ready : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ + state_sampling_ready --> state_sampling_ready : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_sampling_ready --> state_sampling_ready : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ diff --git a/.planning/architecture/mermaid/text_generator_initializer.mmd b/.planning/architecture/mermaid/text_generator_initializer.mmd index e223b665..640e7aff 100644 --- a/.planning/architecture/mermaid/text_generator_initializer.mmd +++ b/.planning/architecture/mermaid/text_generator_initializer.mmd @@ -2,9 +2,10 @@ stateDiagram-v2 direction TB [*] --> idle idle --> preparing_backend : run [always] / begin_initialize_ - preparing_backend --> binding_conditioner : completion_run_ [backend_already_ready_] / none + preparing_backend --> binding_conditioner : completion_run_ [guard_backend_reuse_allowed_] / none preparing_backend_decision --> binding_conditioner : completion_run_ [backend_already_ready_] / none - preparing_backend --> preparing_backend_decision : completion_run_ [backend_prepare_needed_] / request_backend_prepare_ + preparing_backend --> idle : completion_run_ [guard_generation_contract_invalid_] / mark_invalid_request_ + preparing_backend --> preparing_backend_decision : completion_run_ [guard_backend_prepare_allowed_] / request_backend_prepare_ preparing_backend_decision --> binding_conditioner : completion_run_ [backend_prepare_ok_] / accept_prepared_backend_ preparing_backend_decision --> idle : completion_run_ [backend_prepare_invalid_request_] / mark_invalid_request_ preparing_backend_decision --> idle : completion_run_ [backend_prepare_backend_error_] / mark_backend_error_ diff --git a/.planning/architecture/speech_predictor_moshi.md b/.planning/architecture/speech_predictor_moshi.md deleted file mode 100644 index 5e943db6..00000000 --- a/.planning/architecture/speech_predictor_moshi.md +++ /dev/null @@ -1,400 +0,0 @@ -# speech_predictor_moshi - -Source: [`emel/speech/predictor/moshi/sm.hpp`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) - -## Mermaid - -```mermaid -stateDiagram-v2 - direction TB - [*] --> state_uninitialized - state_uninitialized --> state_bind_contract_decision : initialize_run [always] / none - state_bind_contract_decision --> state_binding : completion_initialize_run_ [guard_bind_contract_valid_] / effect_bind_contract_ - state_bind_contract_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_bind_contract_invalid_] / effect_mark_bind_failed_ - state_binding --> state_lmgen_mode_decision : completion_initialize_run_ [always] / none - state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_personaplex_lmgen_] / effect_configure_personaplex_lmgen_ - state_lmgen_mode_decision --> state_configure_lmgen : completion_initialize_run_ [guard_standard_lmgen_] / effect_configure_standard_lmgen_ - state_configure_lmgen --> state_reserve_memory : completion_initialize_run_ [always] / effect_reserve_memory_ - state_reserve_memory --> state_reserve_memory_decision : completion_initialize_run_ [always] / none - state_reserve_memory_decision --> state_allocate_sequence : completion_initialize_run_ [guard_memory_accepted_] / effect_allocate_sequence_ - state_reserve_memory_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ - state_allocate_sequence --> state_allocate_sequence_decision : completion_initialize_run_ [always] / none - state_allocate_sequence_decision --> state_init_error_out_decision : completion_initialize_run_ [guard_memory_accepted_] / none - state_allocate_sequence_decision --> state_init_failed_error_out_decision : completion_initialize_run_ [guard_memory_rejected_] / initialize_run__ - state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ - state_init_error_out_decision --> state_init_callback_decision : completion_initialize_run_ [initialize_run__] / none - state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / initialize_run__ - state_init_failed_error_out_decision --> state_init_failed_callback_decision : completion_initialize_run_ [initialize_run__] / none - state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_done_ - state_init_callback_decision --> state_session_ready : completion_initialize_run_ [initialize_run__] / none - state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / effect_emit_initialize_error_ - state_init_failed_callback_decision --> state_uninitialized : completion_initialize_run_ [initialize_run__] / none - state_session_ready --> state_voice_request_decision : load_voice_run [always] / none - state_voice_request_decision --> state_voice_error_out_decision : completion_load_voice_run_ [guard_voice_contract_valid_] / effect_bind_voice_contract_ - state_voice_request_decision --> state_voice_failed_error_out_decision : completion_load_voice_run_ [guard_voice_contract_invalid_] / load_voice_run__ - state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ - state_voice_error_out_decision --> state_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none - state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ - state_voice_failed_error_out_decision --> state_voice_failed_callback_decision : completion_load_voice_run_ [load_voice_run__] / none - state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_done_ - state_voice_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none - state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ - state_voice_failed_callback_decision --> state_session_ready : completion_load_voice_run_ [load_voice_run__] / none - state_session_ready --> state_prefill_voice_request_decision : prefill_voice_run [always] / none - state_prefill_voice_request_decision --> state_prefill_voice_allocate_slot : completion_prefill_voice_run_ [guard_voice_prefill_request_valid_] / effect_allocate_voice_prefill_slot_ - state_prefill_voice_request_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_prefill_request_invalid_] / prefill_voice_run__ - state_prefill_voice_allocate_slot --> state_prefill_voice_allocate_slot_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_allocate_slot_decision --> state_prefill_voice_capture_memory : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_capture_voice_prefill_memory_ - state_prefill_voice_allocate_slot_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ - state_prefill_voice_capture_memory --> state_prefill_voice_capture_memory_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_capture_memory_decision --> state_prefill_voice_begin : completion_prefill_voice_run_ [guard_memory_accepted_] / effect_begin_voice_prefill_ - state_prefill_voice_capture_memory_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_memory_rejected_] / prefill_voice_run__ - state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f32_] / effect_load_voice_embedding_frame_f32_ - state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_f16_] / effect_load_voice_embedding_frame_f16_ - state_prefill_voice_begin --> state_prefill_voice_embedding_frame : completion_prefill_voice_run_ [guard_voice_embedding_frame_bf16_] / effect_load_voice_embedding_frame_bf16_ - state_prefill_voice_embedding_frame --> state_prefill_voice_embedding_frame_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_embedding_frame_decision --> state_prefill_voice_graph_runtime_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_loaded_] / none - state_prefill_voice_embedding_frame_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_voice_embedding_frame_failed_] / prefill_voice_run__ - state_prefill_voice_graph_runtime_decision --> state_prefill_voice_running_graph : completion_prefill_voice_run_ [guard_graph_runtime_available_] / effect_run_voice_graph_runtime_ - state_prefill_voice_graph_runtime_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_runtime_unavailable_] / prefill_voice_run__ - state_prefill_voice_running_graph --> state_prefill_voice_graph_error_out_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ - state_prefill_voice_graph_error_out_decision --> state_prefill_voice_graph_result_decision : completion_prefill_voice_run_ [guard_no_graph_error_out_] / none - state_prefill_voice_graph_result_decision --> state_prefill_voice_advance : completion_prefill_voice_run_ [guard_graph_step_accepted_] / effect_advance_voice_prefill_ - state_prefill_voice_graph_result_decision --> state_prefill_voice_failed_error_out_decision : completion_prefill_voice_run_ [guard_graph_step_rejected_] / prefill_voice_run__ - state_prefill_voice_advance --> state_prefill_voice_complete_decision : completion_prefill_voice_run_ [always] / none - state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_complete_] / effect_copy_voice_cache_ - state_prefill_voice_complete_decision --> state_prefill_voice_output_decision : completion_prefill_voice_run_ [guard_voice_prefill_pending_] / none - state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_has_voice_complete_out_] / effect_store_voice_complete_out_ - state_prefill_voice_output_decision --> state_prefill_voice_remaining_out_decision : completion_prefill_voice_run_ [guard_no_voice_complete_out_] / none - state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_has_voice_remaining_out_] / effect_store_voice_remaining_out_ - state_prefill_voice_remaining_out_decision --> state_prefill_voice_error_out_decision : completion_prefill_voice_run_ [guard_no_voice_remaining_out_] / none - state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ - state_prefill_voice_error_out_decision --> state_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ - state_prefill_voice_failed_error_out_decision --> state_prefill_voice_failed_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_done_ - state_prefill_voice_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ - state_prefill_voice_failed_callback_decision --> state_session_ready : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_session_ready --> state_personaplex_prompt_begin_decision : begin_personaplex_prompt_run [always] / none - state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_nonempty_valid_] / effect_bind_personaplex_prompt_ - state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_empty_valid_] / effect_bind_empty_personaplex_prompt_ - state_personaplex_prompt_begin_decision --> state_personaplex_prompt_begin_failed_error_out_decision : completion_begin_personaplex_prompt_run_ [guard_personaplex_prompt_begin_invalid_] / begin_personaplex_prompt_run__ - state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ - state_personaplex_prompt_begin_error_out_decision --> state_personaplex_prompt_begin_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ - state_personaplex_prompt_begin_failed_error_out_decision --> state_personaplex_prompt_begin_failed_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_done_ - state_personaplex_prompt_begin_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ - state_personaplex_prompt_begin_failed_callback_decision --> state_session_ready : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_session_ready --> state_prefill_personaplex_prompt_request_decision : prefill_personaplex_prompt_run [always] / none - state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_allocate_slot : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_valid_] / effect_allocate_personaplex_prompt_slot_ - state_prefill_personaplex_prompt_request_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_prefill_request_invalid_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_allocate_slot --> state_prefill_personaplex_prompt_allocate_slot_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_capture_memory : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_capture_personaplex_prompt_memory_ - state_prefill_personaplex_prompt_allocate_slot_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_capture_memory --> state_prefill_personaplex_prompt_capture_memory_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_begin : completion_prefill_personaplex_prompt_run_ [guard_memory_accepted_] / effect_begin_personaplex_prompt_prefill_ - state_prefill_personaplex_prompt_capture_memory_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_memory_rejected_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_begin --> state_prefill_personaplex_prompt_phase_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pre_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_text_pending_] / effect_build_personaplex_prompt_text_frame_ - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_frame : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_post_silence_pending_] / effect_build_personaplex_prompt_silence_frame_ - state_prefill_personaplex_prompt_phase_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_phase_invalid_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_frame --> state_prefill_personaplex_prompt_write_input : completion_prefill_personaplex_prompt_run_ [always] / effect_write_and_build_personaplex_prompt_input_ - state_prefill_personaplex_prompt_write_input --> state_prefill_personaplex_prompt_graph_runtime_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_running_graph : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_available_] / effect_run_personaplex_prompt_graph_runtime_ - state_prefill_personaplex_prompt_graph_runtime_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_runtime_unavailable_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_running_graph --> state_prefill_personaplex_prompt_graph_error_out_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ - state_prefill_personaplex_prompt_graph_error_out_decision --> state_prefill_personaplex_prompt_graph_result_decision : completion_prefill_personaplex_prompt_run_ [guard_no_graph_error_out_] / none - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_pre_silence_] / effect_advance_personaplex_prompt_pre_silence_ - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_text_] / effect_advance_personaplex_prompt_text_ - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_advance : completion_prefill_personaplex_prompt_run_ [guard_graph_step_accepted_personaplex_prompt_post_silence_] / effect_advance_personaplex_prompt_post_silence_ - state_prefill_personaplex_prompt_graph_result_decision --> state_prefill_personaplex_prompt_failed_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_graph_step_rejected_] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_advance --> state_prefill_personaplex_prompt_complete_decision : completion_prefill_personaplex_prompt_run_ [always] / none - state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_complete_] / effect_finish_personaplex_prompt_ - state_prefill_personaplex_prompt_complete_decision --> state_prefill_personaplex_prompt_output_decision : completion_prefill_personaplex_prompt_run_ [guard_personaplex_prompt_pending_] / effect_publish_personaplex_prompt_pending_ - state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_complete_out_] / effect_store_personaplex_prompt_complete_out_ - state_prefill_personaplex_prompt_output_decision --> state_prefill_personaplex_prompt_remaining_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_complete_out_] / none - state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_has_personaplex_prompt_remaining_out_] / effect_store_personaplex_prompt_remaining_out_ - state_prefill_personaplex_prompt_remaining_out_decision --> state_prefill_personaplex_prompt_error_out_decision : completion_prefill_personaplex_prompt_run_ [guard_no_personaplex_prompt_remaining_out_] / none - state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_error_out_decision --> state_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ - state_prefill_personaplex_prompt_failed_error_out_decision --> state_prefill_personaplex_prompt_failed_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_done_ - state_prefill_personaplex_prompt_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ - state_prefill_personaplex_prompt_failed_callback_decision --> state_session_ready : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_session_ready --> state_step_request_decision : step_run [always] / none - state_step_request_decision --> state_allocate_step_slot : completion_step_run_ [guard_step_request_valid_] / effect_allocate_step_slot_ - state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_blocked_by_voice_prompt_] / effect_mark_voice_prompt_pending_ - state_step_request_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_step_request_shape_invalid_] / effect_mark_step_request_invalid_ - state_allocate_step_slot --> state_allocate_step_slot_decision : completion_step_run_ [always] / none - state_allocate_step_slot_decision --> state_capture_memory : completion_step_run_ [guard_memory_accepted_] / effect_capture_memory_ - state_allocate_step_slot_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ - state_capture_memory --> state_capture_memory_decision : completion_step_run_ [always] / none - state_capture_memory_decision --> state_step_begin : completion_step_run_ [guard_memory_accepted_] / effect_begin_step_ - state_capture_memory_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_memory_rejected_] / step_run__ - state_step_begin --> state_input_write_decision : completion_step_run_ [always] / none - state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_full_input_] / effect_write_full_input_ - state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_tail_input_] / effect_write_tail_input_ - state_input_write_decision --> state_build_input_sequence : completion_step_run_ [guard_has_no_input_write_] / none - state_build_input_sequence --> state_graph_runtime_decision : completion_step_run_ [always] / effect_build_input_sequence_ - state_graph_runtime_decision --> state_running_graph : completion_step_run_ [guard_graph_runtime_available_] / effect_run_graph_runtime_ - state_graph_runtime_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_runtime_unavailable_] / step_run__ - state_running_graph --> state_graph_error_out_decision : completion_step_run_ [always] / none - state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_has_graph_error_out_] / effect_store_graph_error_out_ - state_graph_error_out_decision --> state_graph_result_decision : completion_step_run_ [guard_no_graph_error_out_] / none - state_graph_result_decision --> state_depformer_decision : completion_step_run_ [guard_graph_step_accepted_] / none - state_graph_result_decision --> state_step_failed_error_out_decision : completion_step_run_ [guard_graph_step_rejected_] / step_run__ - state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_replace_depformer_tokens_] / effect_replace_audio_with_zero_ - state_depformer_decision --> state_apply_delay_mask : completion_step_run_ [guard_use_graph_audio_tokens_] / none - state_apply_delay_mask --> state_write_generated_decision : completion_step_run_ [always] / effect_apply_delay_mask_and_advance_ - state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_should_write_generated_] / effect_write_generated_ - state_write_generated_decision --> state_skip_delay_decision : completion_step_run_ [guard_provided_input_] / effect_write_generated_missing_ - state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_skip_pending_] / effect_consume_skip_ - state_skip_delay_decision --> state_step_produced_out_decision : completion_step_run_ [guard_before_delay_] / effect_publish_no_output_ - state_skip_delay_decision --> state_collect_output : completion_step_run_ [guard_past_delay_] / effect_collect_delayed_output_ - state_collect_output --> state_output_decision : completion_step_run_ [always] / none - state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_has_ungenerated_] / effect_publish_no_output_ - state_output_decision --> state_step_produced_out_decision : completion_step_run_ [guard_output_complete_] / effect_publish_output_ - state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_has_produced_out_] / effect_store_produced_out_ - state_step_produced_out_decision --> state_step_error_out_decision : completion_step_run_ [guard_no_produced_out_] / none - state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / step_run__ - state_step_error_out_decision --> state_step_callback_decision : completion_step_run_ [step_run__] / none - state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / step_run__ - state_step_failed_error_out_decision --> state_step_failed_callback_decision : completion_step_run_ [step_run__] / none - state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_done_ - state_step_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none - state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / effect_emit_step_error_ - state_step_failed_callback_decision --> state_session_ready : completion_step_run_ [step_run__] / none - state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / step_run__ - state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / step_run__ - state_uninit_step_error_out_decision --> state_uninit_step_callback_decision : completion_step_run_ [step_run__] / none - state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / effect_emit_step_error_ - state_uninit_step_callback_decision --> state_uninitialized : completion_step_run_ [step_run__] / none - state_uninitialized --> state_uninit_voice_error_out_decision : load_voice_run [always] / load_voice_run__ - state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / load_voice_run__ - state_uninit_voice_error_out_decision --> state_uninit_voice_callback_decision : completion_load_voice_run_ [load_voice_run__] / none - state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / effect_emit_load_voice_error_ - state_uninit_voice_callback_decision --> state_uninitialized : completion_load_voice_run_ [load_voice_run__] / none - state_uninitialized --> state_uninit_prefill_voice_error_out_decision : prefill_voice_run [always] / prefill_voice_run__ - state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / prefill_voice_run__ - state_uninit_prefill_voice_error_out_decision --> state_uninit_prefill_voice_callback_decision : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / effect_emit_prefill_voice_error_ - state_uninit_prefill_voice_callback_decision --> state_uninitialized : completion_prefill_voice_run_ [prefill_voice_run__] / none - state_uninitialized --> state_uninit_begin_personaplex_prompt_error_out_decision : begin_personaplex_prompt_run [always] / begin_personaplex_prompt_run__ - state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / begin_personaplex_prompt_run__ - state_uninit_begin_personaplex_prompt_error_out_decision --> state_uninit_begin_personaplex_prompt_callback_decision : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / effect_emit_begin_personaplex_prompt_error_ - state_uninit_begin_personaplex_prompt_callback_decision --> state_uninitialized : completion_begin_personaplex_prompt_run_ [begin_personaplex_prompt_run__] / none - state_uninitialized --> state_uninit_prefill_personaplex_prompt_error_out_decision : prefill_personaplex_prompt_run [always] / prefill_personaplex_prompt_run__ - state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / prefill_personaplex_prompt_run__ - state_uninit_prefill_personaplex_prompt_error_out_decision --> state_uninit_prefill_personaplex_prompt_callback_decision : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / effect_emit_prefill_personaplex_prompt_error_ - state_uninit_prefill_personaplex_prompt_callback_decision --> state_uninitialized : completion_prefill_personaplex_prompt_run_ [prefill_personaplex_prompt_run__] / none - state_session_ready --> state_uninitialized : reset_run [always] / effect_reset_session_ - state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ - state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ -``` - -## Transitions - -| Source | Event | Guard | Action | Target | -| --- | --- | --- | --- | --- | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_bind_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_bind_contract_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_bind_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_bind_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_binding`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_configure_personaplex_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_lmgen_mode_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_configure_standard_lmgen>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_configure_lmgen`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_reserve_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_reserve_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_reserve_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_allocate_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_allocate_sequence_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_initialize_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_initialize_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_init_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`initialize_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_contract_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_voice_contract>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_load_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_voice_prefill_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_capture_voice_prefill_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_begin_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f32>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_f16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_load_voice_embedding_frame_bf16>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_embedding_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_loaded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_embedding_frame_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_embedding_frame_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_run_voice_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_voice_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_copy_voice_cache>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_voice_prefill_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_voice_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_voice_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_voice_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_voice_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_nonempty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_empty_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_bind_empty_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_begin_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_personaplex_prompt_begin_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_personaplex_prompt_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_prefill_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_allocate_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_capture_personaplex_prompt_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_allocate_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_begin_personaplex_prompt_prefill>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_pre_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_text_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_personaplex_prompt_text_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_post_silence_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_personaplex_prompt_silence_frame>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_phase_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_frame`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_and_build_personaplex_prompt_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_write_input`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_run_personaplex_prompt_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_pre_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_text>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_advance_personaplex_prompt_post_silence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_finish_personaplex_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_complete_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_personaplex_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_personaplex_prompt_complete_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_remaining_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_personaplex_prompt_remaining_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_prefill_personaplex_prompt_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_step_request_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_allocate_step_slot>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_step_blocked_by_voice_prompt>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_voice_prompt_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_request_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_step_request_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_step_request_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_allocate_step_slot`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_capture_memory>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_allocate_step_slot_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_capture_memory`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_begin_step>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_capture_memory_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_memory_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_begin`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_full_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_tail_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_input_write_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_no_input_write>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_build_input_sequence`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_build_input_sequence>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_run_graph_runtime>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_graph_runtime_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_runtime_unavailable>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_running_graph`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_graph_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_graph_error_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_accepted>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_graph_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_graph_step_rejected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_replace_depformer_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_replace_audio_with_zero>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_depformer_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_use_graph_audio_tokens>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_apply_delay_mask`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_apply_delay_mask_and_advance>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_should_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_write_generated_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_provided_input>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_write_generated_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_skip_pending>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_consume_skip>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_before_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_skip_delay_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_past_delay>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_collect_delayed_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_collect_output`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_output_has_ungenerated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_no_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_output_complete>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_publish_output>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_has_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_store_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_produced_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_no_produced_out>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_failed_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_step_done>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_step_failed_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_step_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_step_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_load_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`load_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_voice_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_voice_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_voice_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_begin_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_begin_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`begin_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_emit_prefill_personaplex_prompt_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninit_prefill_personaplex_prompt_callback_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`prefill_personaplex_prompt_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_session_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`reset_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | -| [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/sm.hpp) | diff --git a/.planning/architecture/speech_predictor_moshi_executor.md b/.planning/architecture/speech_predictor_moshi_executor.md index d763d6e9..73f64451 100644 --- a/.planning/architecture/speech_predictor_moshi_executor.md +++ b/.planning/architecture/speech_predictor_moshi_executor.md @@ -154,8 +154,12 @@ stateDiagram-v2 state_temporal_out_norm_rms_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_rms_failed_] / effect_mark_graph_execution_unsupported_ state_temporal_out_norm_scale --> state_temporal_out_norm_result_decision : completion_step_run_ [guard_temporal_out_norm_succeeded_] / effect_publish_temporal_out_norm_ state_temporal_out_norm_scale --> state_step_error_out_decision : completion_step_run_ [guard_temporal_out_norm_failed_] / effect_mark_graph_execution_unsupported_ - state_temporal_out_norm_result_decision --> state_text_logits : completion_step_run_ [guard_text_logits_supported_] / effect_bind_text_token_logits_ - state_temporal_out_norm_result_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_temporal_out_norm_result_decision --> state_text_logits_phase_decision : completion_step_run_ [guard_full_graph_phase_] / none + state_temporal_out_norm_result_decision --> state_sampling_ready : completion_step_run_ [guard_prediction_graph_phase_] / effect_publish_prediction_state_ + state_text_logits_phase_decision --> state_text_logits : completion_step_run_ [guard_text_logits_supported_] / effect_bind_text_token_logits_ + state_text_logits_phase_decision --> state_step_error_out_decision : completion_step_run_ [guard_text_logits_unsupported_] / effect_mark_graph_execution_unsupported_ + state_sampling_ready --> state_text_logits : step_run [guard_sampling_step_valid_] / effect_restore_prediction_state_and_bind_text_logits_ + state_sampling_ready --> state_step_error_out_decision : step_run [guard_sampling_step_invalid_] / effect_mark_request_shape_ state_text_logits --> state_text_logits_bind_result_decision : completion_step_run_ [always] / none state_text_logits_bind_result_decision --> state_text_logits_sample_projection : completion_step_run_ [guard_forced_text_token_valid_and_sampling_consume_] / effect_compute_text_token_logits_ state_text_logits_bind_result_decision --> state_text_logits_result_decision : completion_step_run_ [guard_forced_text_token_valid_without_sampling_consume_] / effect_publish_forced_text_token_ @@ -293,8 +297,13 @@ stateDiagram-v2 state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / step_run__ state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / none state_ready --> state_uninitialized : reset [always] / effect_reset_session_ + state_sampling_ready --> state_uninitialized : reset [always] / effect_reset_session_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ + state_ready --> state_ready : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_ready --> state_ready : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ + state_sampling_ready --> state_sampling_ready : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ + state_sampling_ready --> state_sampling_ready : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ ``` ## Transitions @@ -447,8 +456,12 @@ stateDiagram-v2 | [`state_temporal_out_norm_rms_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_rms_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_temporal_out_norm>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_temporal_out_norm_scale`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_temporal_out_norm_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_full_graph_phase>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_temporal_out_norm_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_prediction_graph_phase>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_prediction_state>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_supported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_bind_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_text_logits_phase_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_text_logits_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_graph_execution_unsupported>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_step_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_restore_prediction_state_and_bind_text_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_sampling_step_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_request_shape>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_and_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_compute_text_token_logits>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_sample_projection`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_text_logits_bind_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_forced_text_token_valid_without_sampling_consume>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_publish_forced_text_token>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_text_logits_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | @@ -586,5 +599,10 @@ stateDiagram-v2 | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | diff --git a/.planning/architecture/text_generator_initializer.md b/.planning/architecture/text_generator_initializer.md index cb5460cc..139b877a 100644 --- a/.planning/architecture/text_generator_initializer.md +++ b/.planning/architecture/text_generator_initializer.md @@ -9,9 +9,10 @@ stateDiagram-v2 direction TB [*] --> idle idle --> preparing_backend : run [always] / begin_initialize_ - preparing_backend --> binding_conditioner : completion_run_ [backend_already_ready_] / none + preparing_backend --> binding_conditioner : completion_run_ [guard_backend_reuse_allowed_] / none preparing_backend_decision --> binding_conditioner : completion_run_ [backend_already_ready_] / none - preparing_backend --> preparing_backend_decision : completion_run_ [backend_prepare_needed_] / request_backend_prepare_ + preparing_backend --> idle : completion_run_ [guard_generation_contract_invalid_] / mark_invalid_request_ + preparing_backend --> preparing_backend_decision : completion_run_ [guard_backend_prepare_allowed_] / request_backend_prepare_ preparing_backend_decision --> binding_conditioner : completion_run_ [backend_prepare_ok_] / accept_prepared_backend_ preparing_backend_decision --> idle : completion_run_ [backend_prepare_invalid_request_] / mark_invalid_request_ preparing_backend_decision --> idle : completion_run_ [backend_prepare_backend_error_] / mark_backend_error_ @@ -64,9 +65,10 @@ stateDiagram-v2 | Source | Event | Guard | Action | Target | | --- | --- | --- | --- | --- | | [`idle`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`begin_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`preparing_backend`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | -| [`preparing_backend`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`backend_already_ready>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`binding_conditioner`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | +| [`preparing_backend`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`guard_backend_reuse_allowed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`binding_conditioner`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | | [`preparing_backend_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`backend_already_ready>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`binding_conditioner`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | -| [`preparing_backend`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`backend_prepare_needed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`request_backend_prepare>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`preparing_backend_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | +| [`preparing_backend`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`guard_generation_contract_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`mark_invalid_request>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`idle`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | +| [`preparing_backend`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`guard_backend_prepare_allowed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`request_backend_prepare>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`preparing_backend_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | | [`preparing_backend_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`backend_prepare_ok>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`accept_prepared_backend>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`binding_conditioner`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | | [`preparing_backend_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`backend_prepare_invalid_request>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`mark_invalid_request>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`idle`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | | [`preparing_backend_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`backend_prepare_backend_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`mark_backend_error>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | [`idle`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/text/generator/initializer/sm.hpp) | diff --git a/README.md b/README.md index 9a3be623..7de9b1e8 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,6 @@ environments, while Zig remains the default for day-to-day builds. - [`.planning/architecture/speech_decoder_whisper.md`](.planning/architecture/speech_decoder_whisper.md) - [`.planning/architecture/speech_encoder_whisper.md`](.planning/architecture/speech_encoder_whisper.md) - [`.planning/architecture/speech_predictor_moshi_executor.md`](.planning/architecture/speech_predictor_moshi_executor.md) -- [`.planning/architecture/speech_predictor_moshi.md`](.planning/architecture/speech_predictor_moshi.md) - [`.planning/architecture/speech_tokenizer_moshi.md`](.planning/architecture/speech_tokenizer_moshi.md) - [`.planning/architecture/tensor_view.md`](.planning/architecture/tensor_view.md) - [`.planning/architecture/text_conditioner.md`](.planning/architecture/text_conditioner.md) @@ -256,4 +255,4 @@ Generated from `scripts/embedded_size.sh --snapshot-update` using final dead-str - Ratio (`emel / reference`) stripped: `1.457x` - Ratio (`emel / reference`) section: `0.428x` -This is a matched Qwen3-0.6B end-to-end runner size measurement for the maintained `hello` -> first-token path, not a whole-product feature-parity claim. Both binaries still include the platform runtime selected by the toolchain. +This is a matched Qwen3-0.6B end-to-end runner size measurement for the maintained `hello` -> first-token path, not a whole-product feature-parity claim. Both binaries still include the platform runtime selected by the toolchain. \ No newline at end of file diff --git a/docs/benchmarking.md b/docs/benchmarking.md index 4bda7403..ebb81a2b 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -403,6 +403,8 @@ temporal-state buffer and performs text logits, text sampling, depformer executi sampling. `moshi_reference_driver personaplex` links only the pinned moshi.cpp/ggml reference lane. the reference configure hard-disables Metal and the script injects `--threads 1`, seed `1234`, 125 frames, temperatures, and sampling limits; there are no process-global EMEL sampling defaults. +The EMEL composition also injects the Park-Miller modulus and zero-seed replacement state; nonzero +external seeds are normalized into the valid actor-owned RNG state range before sampling. the pinned upstream JSON remains untouched for the reference lane. EMEL model conversion injects the separate `tools/bench/personaplex-inference.json` contract, keeping prompt tokens, public diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index 6e21e7a0..eb8df14a 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -369,6 +369,9 @@ src/emel/speech/encoder/whisper/any.hpp src/emel/speech/encoder/whisper/context.hpp src/emel/speech/encoder/whisper/errors.hpp src/emel/speech/encoder/whisper/guards.hpp +src/emel/speech/predictor/moshi/executor/actions.hpp +src/emel/speech/predictor/moshi/executor/guards.hpp +src/emel/speech/predictor/moshi/guards.hpp src/emel/speech/recognizer/detail.hpp src/emel/speech/recognizer/errors.hpp src/emel/speech/tokenizer/whisper/detail.hpp @@ -612,6 +615,7 @@ tests/sm/sm_external_completion_tests.cpp tests/sm/sm_policy_tests.cpp tests/speech/decoder/whisper/lifecycle_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp +tests/speech/predictor/moshi_lifecycle_tests.cpp tests/speech/tokenizer/moshi/lifecycle_tests.cpp tests/speech/tokenizer/whisper_tests.cpp tests/tensor/view/lifecycle_tests.cpp diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 8a40f44e..ecd7ae68 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -98,7 +98,10 @@ struct effect_bind_depformer_fused_projection_layout { struct effect_bind_nonzero_sampling_seed { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { - ctx.sampling.random_state = runtime_ev.request.sampling_seed; + ctx.sampling.random_state = + ((runtime_ev.request.sampling_seed - 1u) % + (ctx.policy.sampling_modulus - 1u)) + + 1u; } }; diff --git a/src/emel/speech/predictor/moshi/executor/context.hpp b/src/emel/speech/predictor/moshi/executor/context.hpp index c9bea34f..197f9fca 100644 --- a/src/emel/speech/predictor/moshi/executor/context.hpp +++ b/src/emel/speech/predictor/moshi/executor/context.hpp @@ -23,6 +23,7 @@ struct kv_views { struct policies { float rms_norm_epsilon = 0.0f; uint32_t zero_seed_state = 0u; + uint32_t sampling_modulus = 0u; int32_t token_zero = 0; }; diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 34d60e60..0dc53926 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "emel/model/loader/errors.hpp" @@ -14,6 +15,14 @@ struct guard_bind_contract_valid { bool operator()(const event::initialize_run &runtime_ev, const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; + const bool sampling_config_valid = + !runtime_ev.request.sampling_enabled || + (std::isfinite(runtime_ev.request.sampling_audio_temperature) && + runtime_ev.request.sampling_audio_temperature > 0.0f && + std::isfinite(runtime_ev.request.sampling_text_temperature) && + runtime_ev.request.sampling_text_temperature > 0.0f && + runtime_ev.request.sampling_audio_top_k > 0 && + runtime_ev.request.sampling_text_top_k > 0); return emel::model::moshi::detail::validate_execution_contract(model) == emel::error::cast(emel::model::loader::error::none) && model.moshi_component_id == emel::model::data::moshi_component::lm && @@ -22,8 +31,11 @@ struct guard_bind_contract_valid { model.moshi_lm.text_card > 0 && model.moshi_lm.card > 0 && model.moshi_lm.dim > 0 && (!runtime_ev.request.sampling_enabled || ctx.sampler != nullptr) && + sampling_config_valid && ctx.policy.rms_norm_epsilon > 0.0f && - ctx.policy.zero_seed_state != 0u && ctx.policy.token_zero < 0 && + ctx.policy.sampling_modulus > 1u && + ctx.policy.zero_seed_state % ctx.policy.sampling_modulus != 0u && + ctx.policy.token_zero < 0 && ctx.capacity.hidden_dim > 0u && ctx.capacity.hidden_dim <= detail::k_max_hidden_dim && ctx.capacity.temporal_context > 0u && diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 2ce95e0a..1563aa05 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -1030,6 +1030,22 @@ struct model { + sml::unexpected_event [ guard::guard_unexpected_error_out_absent{} ] / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_present{} ] + / action::effect_mark_unexpected_and_store{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_absent{} ] + / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_present{} ] + / action::effect_mark_unexpected_and_store{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_absent{} ] + / action::effect_mark_unexpected{} ); // clang-format on } diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 0ffb3524..ad122f83 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -25,7 +25,8 @@ struct guard_bind_contract_valid { const bool personaplex = lm.depformer_weights_per_step; const int32_t delayed_dep_q = personaplex ? lm.inference_dep_q : lm.dep_q; const int32_t needed_tokens = codebook_count - delayed_dep_q - 1; - const int32_t row_count = max_delay + 2 + static_cast(personaplex); + const int64_t row_count = static_cast(max_delay) + 2 + + static_cast(personaplex); const bool inference_contract = !personaplex || (lm.inference_dep_q > 0 && lm.inference_dep_q <= lm.dep_q && @@ -105,8 +106,7 @@ struct guard_voice_contract_valid { embeddings->n_dims == 4 && embeddings->dims[0] == ctx.session.model->moshi_lm.dim && embeddings->dims[1] == 1 && embeddings->dims[2] == 1 && - embeddings->dims[3] > 0 && - embeddings->dims[3] <= + embeddings->dims[3] > 0 && embeddings->dims[0] <= static_cast(event::k_max_voice_embedding_dim) && embedding_type_ok && cache->n_dims == 2 && cache->dims[0] == ctx.lmgen.cache_row_count && @@ -321,9 +321,10 @@ struct guard_voice_prefill_pending { struct guard_personaplex_prompt_begin_valid { bool operator()(const event::begin_personaplex_prompt_run &runtime_ev, const action::context &ctx) const noexcept { - const int32_t frame_count = runtime_ev.request.pre_text_silence_frames + - runtime_ev.request.text_token_count + - runtime_ev.request.post_text_silence_frames; + const int64_t frame_count = + static_cast(runtime_ev.request.pre_text_silence_frames) + + static_cast(runtime_ev.request.text_token_count) + + static_cast(runtime_ev.request.post_text_silence_frames); return ctx.session.model != nullptr && ctx.voice.loaded && ctx.voice.ready && !ctx.voice.prompt_ready && !ctx.voice.prompt_started && @@ -339,9 +340,10 @@ struct guard_personaplex_prompt_begin_valid { struct guard_personaplex_prompt_begin_nonempty_valid { bool operator()(const event::begin_personaplex_prompt_run &runtime_ev, const action::context &ctx) const noexcept { - const int32_t frame_count = runtime_ev.request.pre_text_silence_frames + - runtime_ev.request.text_token_count + - runtime_ev.request.post_text_silence_frames; + const int64_t frame_count = + static_cast(runtime_ev.request.pre_text_silence_frames) + + static_cast(runtime_ev.request.text_token_count) + + static_cast(runtime_ev.request.post_text_silence_frames); return guard_personaplex_prompt_begin_valid{}(runtime_ev, ctx) && frame_count > 0; } @@ -350,15 +352,18 @@ struct guard_personaplex_prompt_begin_nonempty_valid { struct guard_personaplex_prompt_begin_empty_valid { bool operator()(const event::begin_personaplex_prompt_run &runtime_ev, const action::context &ctx) const noexcept { - const int32_t frame_count = runtime_ev.request.pre_text_silence_frames + - runtime_ev.request.text_token_count + - runtime_ev.request.post_text_silence_frames; + const int64_t frame_count = + static_cast(runtime_ev.request.pre_text_silence_frames) + + static_cast(runtime_ev.request.text_token_count) + + static_cast(runtime_ev.request.post_text_silence_frames); const auto *model = ctx.session.model; - const int32_t default_frame_count = + const int64_t default_frame_count = model == nullptr ? -1 - : model->moshi_lm.inference_pre_text_silence_frames + - model->moshi_lm.inference_post_text_silence_frames; + : static_cast( + model->moshi_lm.inference_pre_text_silence_frames) + + static_cast( + model->moshi_lm.inference_post_text_silence_frames); return guard_personaplex_prompt_begin_valid{}(runtime_ev, ctx) && frame_count == 0 && default_frame_count > 0 && default_frame_count <= action::k_max_delay_rows; diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 68fc68df..1408bc66 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -726,6 +726,30 @@ template struct model { + sml::unexpected_event [ guard::guard_unexpected_error_out_absent{} ] / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_present{} ] + / action::effect_mark_unexpected_and_store{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_absent{} ] + / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_present{} ] + / action::effect_mark_unexpected_and_store{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_absent{} ] + / action::effect_mark_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_present{} ] + / action::effect_mark_unexpected_and_store{} + , sml::state <= sml::state + + sml::unexpected_event + [ guard::guard_unexpected_error_out_absent{} ] + / action::effect_mark_unexpected{} ); // clang-format on } diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index 8015ea52..fa2a8d35 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -108,6 +108,7 @@ TEST_CASE( executor::action::policies{ .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, + .sampling_modulus = 2147483647u, .token_zero = -1, }, .capacity = diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 60830721..4b3e296e 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ moshi_executor::dependencies make_executor_dependencies( moshi_executor::action::policies{ .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, + .sampling_modulus = 2147483647u, .token_zero = -1, }, .capacity = @@ -984,6 +986,88 @@ TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { CHECK(err == emel::error::cast(moshi_executor::error::none)); } +TEST_CASE("speech_moshi_executor_normalizes_nonzero_sampling_seed") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::kernel::sm kernel{}; + auto dependencies = make_executor_dependencies(kernel); + moshi_executor::action::context ctx{dependencies}; + moshi_executor::event::initialize init{*fixture.model}; + init.sampling_seed = 2147483647u; + moshi_executor::event::initialize_ctx init_ctx{}; + moshi_executor::event::initialize_run init_run{init, init_ctx}; + + moshi_executor::action::effect_bind_nonzero_sampling_seed{}(init_run, ctx); + CHECK(ctx.sampling.random_state > 0u); + CHECK(ctx.sampling.random_state < 2147483647u); +} + +TEST_CASE("speech_moshi_executor_rejects_invalid_sampling_configuration") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + const auto rejected = [&fixture](const float audio_temperature, + const float text_temperature, + const int32_t audio_top_k, + const int32_t text_top_k) { + emel::kernel::sm kernel{}; + emel::logits::sampler::sm sampler{}; + moshi_executor::sm executor{ + make_executor_dependencies(kernel, {}, &sampler)}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.sampling_enabled = true; + init.sampling_audio_temperature = audio_temperature; + init.sampling_text_temperature = text_temperature; + init.sampling_audio_top_k = audio_top_k; + init.sampling_text_top_k = text_top_k; + init.sampling_seed = 1234u; + init.error_out = &err; + return !executor.process_event(init) && + err == emel::error::cast(moshi_executor::error::bind_failed); + }; + + CHECK(rejected(std::numeric_limits::quiet_NaN(), 0.7f, 1, 1)); + CHECK(rejected(0.8f, std::numeric_limits::quiet_NaN(), 1, 1)); + CHECK(rejected(0.8f, 0.7f, 0, 1)); + CHECK(rejected(0.8f, 0.7f, 1, 0)); +} + +TEST_CASE("speech_moshi_machines_report_unexpected_events_after_init") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::kernel::sm kernel{}; + moshi_executor::sm executor{make_executor_dependencies(kernel)}; + emel::error::type executor_err = k_no_error; + moshi_executor::event::initialize executor_init{*fixture.model}; + executor_init.error_out = &executor_err; + REQUIRE(executor.process_event(executor_init)); + executor_err = k_no_error; + CHECK_FALSE(executor.process_event(executor_init)); + CHECK(executor_err == + emel::error::cast(moshi_executor::error::unexpected_event)); + + emel::memory::hybrid::sm memory{}; + recording_graph_executor graph{}; + moshi::sm predictor{make_predictor_dependencies(graph, memory)}; + emel::error::type predictor_err = k_no_error; + moshi::event::initialize predictor_init{*fixture.model}; + configure_predictor_initialize(predictor_init); + predictor_init.error_out = &predictor_err; + REQUIRE(predictor.process_event(predictor_init)); + predictor_err = k_no_error; + CHECK_FALSE(predictor.process_event(predictor_init)); + CHECK(predictor_err == emel::error::cast(moshi::error::unexpected_event)); +} + TEST_CASE("speech_moshi_executor_requires_sampler_for_sampling") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { @@ -1079,6 +1163,11 @@ TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { read_binary_file(repo_root() / "src" / "emel" / "speech" / "predictor" / "moshi" / "executor" / "detail.hpp"); const std::string detail_source{detail_bytes.begin(), detail_bytes.end()}; + const auto predictor_guard_bytes = + read_binary_file(repo_root() / "src" / "emel" / "speech" / + "predictor" / "moshi" / "guards.hpp"); + const std::string predictor_guards_source{predictor_guard_bytes.begin(), + predictor_guard_bytes.end()}; CHECK(source.find("infer_debug_phase") == std::string::npos); CHECK(source.find("debug_phase_out != nullptr") == std::string::npos); @@ -1143,6 +1232,14 @@ TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { CHECK(actions_source.find("effect_bind_zero_sampling_seed") != std::string::npos); CHECK(detail_source.find("random_state == 0u") == std::string::npos); + CHECK(predictor_guards_source.find("const int64_t row_count") != + std::string::npos); + CHECK(predictor_guards_source.find("const int64_t frame_count") != + std::string::npos); + CHECK(predictor_guards_source.find("const int64_t default_frame_count") != + std::string::npos); + CHECK(predictor_guards_source.find("embeddings->dims[0] <=") != + std::string::npos); CHECK(actions_source.find("effect_publish_temporal_out_norm") != std::string::npos); CHECK(actions_source.find("struct effect_run_temporal_layer_norm {") == diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index 5f5d1e00..a115b75b 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -541,6 +541,7 @@ int main(int argc, char **argv) { runtime::policies{ .rms_norm_epsilon = 1.0e-8f, .zero_seed_state = 123459876u, + .sampling_modulus = 2147483647u, .token_zero = -1, }, .capacity = From 116d89f9c39e63aebb44a969e4a9e57bc95877c2 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 09:34:43 -0500 Subject: [PATCH 48/61] fix PersonaPlex comparison review issues --- docs/benchmarking.md | 8 ++- scripts/bench_mimi_compare.sh | 43 ++++++----- scripts/bench_personaplex_compare.sh | 16 +++-- src/emel/model/moshi/detail.cpp | 23 ++++++ tests/model/moshi/binding_tests.cpp | 71 +++++++++++++++++++ tools/bench/personaplex-inference.json | 4 +- tools/bench/personaplex_compare.py | 24 ++++--- tools/bench/personaplex_compare_tests.cpp | 25 ++++++- tools/bench/speech/moshi_reference_driver.cpp | 19 ++--- 9 files changed, 181 insertions(+), 52 deletions(-) diff --git a/docs/benchmarking.md b/docs/benchmarking.md index ebb81a2b..8494a2fe 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -402,14 +402,16 @@ after temporal normalization in `sampling_ready`, then the sample RTC restores t temporal-state buffer and performs text logits, text sampling, depformer execution, and audio sampling. `moshi_reference_driver personaplex` links only the pinned moshi.cpp/ggml reference lane. the reference configure hard-disables Metal and the script injects `--threads 1`, seed `1234`, 125 -frames, temperatures, and sampling limits; there are no process-global EMEL sampling defaults. +frames, and temperatures. The shared inference contract injects the fixed reference-compatible +audio/text top-k limits into EMEL; asymmetric command-line sampling overrides are intentionally not +exposed. There are no process-global EMEL sampling defaults. The EMEL composition also injects the Park-Miller modulus and zero-seed replacement state; nonzero external seeds are normalized into the valid actor-owned RNG state range before sampling. the pinned upstream JSON remains untouched for the reference lane. EMEL model conversion injects the separate `tools/bench/personaplex-inference.json` contract, keeping prompt tokens, public -codebook count, and silence framing explicit and reproducible. the setup keeps the full 16-codebook -Mimi parity artifact separate from PersonaPlex's 8-public-codebook Mimi artifact. +codebook count, silence framing, and sampling limits explicit and reproducible. the setup keeps the +full 16-codebook Mimi parity artifact separate from PersonaPlex's 8-public-codebook Mimi artifact. the report and both audible WAVs are written under `build/personaplex_compare/`. the report records the input SHA256, EMEL/reference LM and Mimi paths and SHA256 values, exact public Mimi input-code diff --git a/scripts/bench_mimi_compare.sh b/scripts/bench_mimi_compare.sh index 40f5d9e9..83e4a482 100755 --- a/scripts/bench_mimi_compare.sh +++ b/scripts/bench_mimi_compare.sh @@ -48,13 +48,6 @@ while [[ $# -gt 0 ]]; do esac done -for tool in cmake ninja git; do - if ! command -v "$tool" >/dev/null 2>&1; then - echo "error: required tool missing: $tool" >&2 - exit 1 - fi -done - # Discover the interpreter the same way the MLX setup script does, so hosts # that ship python3.12/python3.13 without a python3 shim (the environment the # setup path supports) can run the WAV generation and comparison steps too. @@ -71,22 +64,13 @@ if [[ -z "$PYTHON_BIN" ]]; then echo "error: required tool missing: python3 (or python3.12/python3.13)" >&2 exit 1 fi -if [[ ! -f "$MODEL_CONFIG" ]]; then - echo "error: missing pinned PersonaPlex model config: $MODEL_CONFIG" >&2 - exit 1 -fi -MIMI_N_Q="$($PYTHON_BIN - "$MODEL_CONFIG" <<'PY' -import json -import sys - -value = json.load(open(sys.argv[1], encoding="utf-8")).get("n_q") -if not isinstance(value, int) or value <= 0: - raise SystemExit("Mimi n_q must be a positive integer") -print(value) -PY -)" - if ! $RUN_ONLY; then + for tool in cmake ninja git; do + if ! command -v "$tool" >/dev/null 2>&1; then + echo "error: required build tool missing: $tool" >&2 + exit 1 + fi + done # full mode: fetch + sha256 verify + run the emel converter (no build) # build_targets is always non-empty: the MLX lane drives its reference # through the Python shim only (no reference build target), while the @@ -112,6 +96,21 @@ if ! $RUN_ONLY; then --target "${build_targets[@]}" fi +if [[ ! -f "$MODEL_CONFIG" ]]; then + echo "error: missing pinned PersonaPlex model config: $MODEL_CONFIG" >&2 + exit 1 +fi +MIMI_N_Q="$($PYTHON_BIN - "$MODEL_CONFIG" <<'PY' +import json +import sys + +value = json.load(open(sys.argv[1], encoding="utf-8")).get("n_q") +if not isinstance(value, int) or value <= 0: + raise SystemExit("Mimi n_q must be a positive integer") +print(value) +PY +)" + if $BUILD_ONLY; then echo "mimi compare lanes built in $BUILD_DIR" exit 0 diff --git a/scripts/bench_personaplex_compare.sh b/scripts/bench_personaplex_compare.sh index e35dbb3a..7e31a570 100755 --- a/scripts/bench_personaplex_compare.sh +++ b/scripts/bench_personaplex_compare.sh @@ -63,14 +63,18 @@ for value in "$FRAMES" "$SEED" "$THREADS"; do exit 1 fi done -for tool in cmake ninja git python3 zig; do - if ! command -v "$tool" >/dev/null 2>&1; then - echo "error: required tool missing: $tool" >&2 - exit 1 - fi -done +if ! command -v python3 >/dev/null 2>&1; then + echo "error: required tool missing: python3" >&2 + exit 1 +fi if ! $RUN_ONLY; then + for tool in cmake ninja git zig; do + if ! command -v "$tool" >/dev/null 2>&1; then + echo "error: required build tool missing: $tool" >&2 + exit 1 + fi + done "$ROOT_DIR/scripts/setup_moshi_cpp_reference.sh" >/dev/null zig_bin="$(command -v zig)" cmake -S "$ROOT_DIR/tools/bench" -B "$BUILD_DIR" -G Ninja \ diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index 4c259075..321737cb 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -1,5 +1,6 @@ #include "emel/model/moshi/detail.hpp" +#include #include #include #include @@ -788,6 +789,22 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, return emel::error::cast(emel::model::loader::error::model_invalid); } + std::array + required_weight_indices = {}; + if (lm.depformer_weights_per_step && + lm.depformer_weight_schedule_count > 0u) { + for (uint32_t index = 0u; index < lm.depformer_weight_schedule_count; + ++index) { + const int32_t weight_index = lm.depformer_weight_schedule[index]; + if (weight_index < 0 || weight_index >= lm.dep_q) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + required_weight_indices[static_cast(weight_index)] = true; + } + } else { + std::fill_n(required_weight_indices.begin(), lm.dep_q, true); + } + const auto *depformer_text_embedding = find_tensor(model_data, "lm.depformer_text_emb.weight"); if (depformer_text_embedding == nullptr) { @@ -799,6 +816,9 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, *depformer_text_embedding), }; for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + if (!required_weight_indices[static_cast(codebook)]) { + continue; + } char name[96] = {}; int written = std::snprintf(name, sizeof(name), "lm.depformer_in.%d.weight", codebook); @@ -880,6 +900,9 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, return emel::error::cast(emel::model::loader::error::model_invalid); } for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + if (!required_weight_indices[static_cast(codebook)]) { + continue; + } auto &codebook_layer = layer.codebooks[static_cast(codebook)]; written = std::snprintf(name, sizeof(name), diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index 7c905b24..940d1796 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -574,6 +574,77 @@ TEST_CASE("moshi lm contract requires every split depformer input projection") { CHECK(moshi::validate_execution_contract(*model) != k_none); } +TEST_CASE("moshi lm contract binds only scheduled depformer weight sets") { + auto loaded = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (loaded.model == nullptr) { + return; + } + + auto model = std::make_unique(*loaded.model); + model->moshi_lm.depformer_weights_per_step = true; + model->moshi_lm.depformer_weight_schedule_count = 4u; + model->moshi_lm.depformer_weight_schedule[0] = 0; + model->moshi_lm.depformer_weight_schedule[1] = 1; + model->moshi_lm.depformer_weight_schedule[2] = 1; + model->moshi_lm.depformer_weight_schedule[3] = 2; + + for (uint32_t index = 0; index < model->n_tensors; ++index) { + auto &tensor = model->tensors[index]; + const std::string_view name{ + model->name_storage.data() + tensor.name_offset, tensor.name_length}; + const std::size_t codebook = name.find(".3."); + if ((name.starts_with("lm.depformer_in.") || + name.starts_with("lm.depformer.layers.")) && + codebook != std::string_view::npos) { + model->name_storage[tensor.name_offset + codebook + 1u] = '9'; + } + } + + CHECK(moshi::validate_execution_contract(*model) == k_none); +} + +TEST_CASE("moshi lm contract rejects invalid scheduled tensor bindings") { + auto loaded = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (loaded.model == nullptr) { + return; + } + + auto model = std::make_unique(*loaded.model); + const auto hide_tensor = [&model](const std::string_view target, + const size_t changed_character) { + for (uint32_t index = 0; index < model->n_tensors; ++index) { + auto &tensor = model->tensors[index]; + const std::string_view name{ + model->name_storage.data() + tensor.name_offset, tensor.name_length}; + if (name == target) { + model->name_storage[tensor.name_offset + changed_character] = '9'; + return true; + } + } + return false; + }; + + SUBCASE("schedule index must be in range") { + model->moshi_lm.depformer_weights_per_step = true; + model->moshi_lm.depformer_weight_schedule_count = 1u; + model->moshi_lm.depformer_weight_schedule[0] = model->moshi_lm.dep_q; + } + SUBCASE("text embedding is required") { + constexpr std::string_view name = "lm.depformer_text_emb.weight"; + REQUIRE(hide_tensor(name, name.size() - 1u)); + } + SUBCASE("scheduled input projection is required") { + constexpr std::string_view name = "lm.depformer_in.1.weight"; + REQUIRE(hide_tensor(name, name.find(".1.") + 1u)); + } + SUBCASE("codebook output projection is required") { + constexpr std::string_view name = "lm.linears.1.weight"; + REQUIRE(hide_tensor(name, name.find(".1.") + 1u)); + } + + CHECK(moshi::validate_execution_contract(*model) != k_none); +} + TEST_CASE("enriched mimi fixture loads hparams and contract") { auto loaded = load_fixture_or_skip("mimi-tiny.gguf"); if (loaded.model == nullptr) { diff --git a/tools/bench/personaplex-inference.json b/tools/bench/personaplex-inference.json index 0f66b62b..c1c42155 100644 --- a/tools/bench/personaplex-inference.json +++ b/tools/bench/personaplex-inference.json @@ -24,5 +24,7 @@ "max_blocks": 256, "block_tokens": 4, "prompt_text_token": -1, - "frame_samples": 1920 + "frame_samples": 1920, + "audio_top_k": 250, + "text_top_k": 25 } diff --git a/tools/bench/personaplex_compare.py b/tools/bench/personaplex_compare.py index 491ec76c..3118a1f6 100755 --- a/tools/bench/personaplex_compare.py +++ b/tools/bench/personaplex_compare.py @@ -70,9 +70,11 @@ def match_fraction(left: list[list[int]], right: list[list[int]], streams: int) matched = 0 total = 0 for left_frame, right_frame in zip(left, right): - width = min(streams, len(left_frame), len(right_frame)) - matched += sum(a == b for a, b in zip(left_frame[:width], right_frame[:width])) - total += width + if len(left_frame) < streams or len(right_frame) < streams: + return 0.0 + matched += sum(a == b for a, b in + zip(left_frame[:streams], right_frame[:streams])) + total += streams return matched / total if total else 0.0 @@ -173,8 +175,6 @@ def main() -> int: parser.add_argument("--threads", type=int, default=1) parser.add_argument("--audio-temperature", type=float, default=0.8) parser.add_argument("--text-temperature", type=float, default=0.7) - parser.add_argument("--audio-top-k", type=int, default=250) - parser.add_argument("--text-top-k", type=int, default=25) parser.add_argument("--min-output-match", type=float, default=0.15) parser.add_argument("--min-first-four-match", type=float, default=0.30) parser.add_argument("--min-energy-correlation", type=float, default=0.30) @@ -187,7 +187,7 @@ def main() -> int: inference = json.loads(inference_path.read_text(encoding="utf-8")) required_inference = ( "dep_q", "max_blocks", "block_tokens", "prompt_text_token", - "frame_samples") + "frame_samples", "audio_top_k", "text_top_k") if any(not isinstance(inference.get(key), int) for key in required_inference): parser.error("inference config integer contract is incomplete") @@ -196,11 +196,13 @@ def main() -> int: block_tokens = inference["block_tokens"] prompt_text_token = inference["prompt_text_token"] frame_samples = inference["frame_samples"] + audio_top_k = inference["audio_top_k"] + text_top_k = inference["text_top_k"] if (public_n_q <= 0 or max_blocks <= 0 or block_tokens <= 0 or - frame_samples <= 0): + frame_samples <= 0 or audio_top_k <= 0 or text_top_k <= 0): parser.error( - "inference dep_q, max_blocks, block_tokens, and frame_samples must " - "be positive") + "inference dep_q, max_blocks, block_tokens, frame_samples, and top-k " + "limits must be positive") output_dir = Path(args.output_dir) output_dir.mkdir(parents=True, exist_ok=True) @@ -222,8 +224,8 @@ def main() -> int: str(args.seed), str(args.audio_temperature), str(args.text_temperature), - str(args.audio_top_k), - str(args.text_top_k), + str(audio_top_k), + str(text_top_k), str(max_blocks), str(block_tokens), str(prompt_text_token), diff --git a/tools/bench/personaplex_compare_tests.cpp b/tools/bench/personaplex_compare_tests.cpp index dd4f7e62..c1164c40 100644 --- a/tools/bench/personaplex_compare_tests.cpp +++ b/tools/bench/personaplex_compare_tests.cpp @@ -74,6 +74,7 @@ TEST_CASE("personaplex compare math reports exact and partial token behavior") { "); m=importlib.util.module_from_spec(spec); spec.loader.exec_module(m); " "assert m.match_fraction([[1,2],[3,4]], [[1,2],[3,4]], 2) == 1.0; " "assert m.match_fraction([[1,9]], [[1,2]], 2) == 0.5; " + "assert m.match_fraction([[1]], [[1,2]], 2) == 0.0; " "assert m.common_token_prefix([[1,2]], [[1,3]]) == 1; " "assert abs(m.correlation([1.0,2.0,3.0], [2.0,4.0,6.0])-1.0) < 1e-12"; CHECK(command_exit_code("python3 -c " + quote_arg_posix(program)) == 0); @@ -94,6 +95,11 @@ TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { read_file(repo_root() / "tools" / "bench" / "moshi_gguf_convert.py"); const std::string inference_source = read_file(repo_root() / "tools" / "bench" / "personaplex-inference.json"); + const std::string mimi_wrapper_source = + read_file(repo_root() / "scripts" / "bench_mimi_compare.sh"); + const std::string reference_source = + read_file(repo_root() / "tools" / "bench" / "speech" / + "moshi_reference_driver.cpp"); const std::size_t first_public_match = compare_source.find("public_codebook_match_fraction"); @@ -127,6 +133,8 @@ TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { CHECK(emel_source.find("sampling_seed = 1234") == std::string::npos); CHECK(emel_source.find(".max_blocks = 256") == std::string::npos); CHECK(compare_source.find("\"--n-q\", \"8\"") == std::string::npos); + CHECK(compare_source.find("--audio-top-k") == std::string::npos); + CHECK(compare_source.find("--text-top-k") == std::string::npos); CHECK(compare_source.find("\"emel_lm\": {") != std::string::npos); CHECK(compare_source.find("\"reference_lm\": {") != std::string::npos); CHECK(compare_source.find("\"emel_mimi\": {") != std::string::npos); @@ -135,6 +143,21 @@ TEST_CASE("personaplex compare keeps CPU and lane isolation explicit") { std::string::npos); CHECK(converter_source.find("--inference-config") != std::string::npos); CHECK(inference_source.find("\"prompt_tokens\"") != std::string::npos); + CHECK(inference_source.find("\"audio_top_k\"") != std::string::npos); + CHECK(inference_source.find("\"text_top_k\"") != std::string::npos); + const std::size_t personaplex_build_guard = + wrapper_source.find("if ! $RUN_ONLY; then"); + REQUIRE(personaplex_build_guard != std::string::npos); + CHECK(wrapper_source.find("for tool in cmake ninja git zig", + personaplex_build_guard) != std::string::npos); + const std::size_t mimi_build_guard = + mimi_wrapper_source.find("if ! $RUN_ONLY; then"); + REQUIRE(mimi_build_guard != std::string::npos); + CHECK(mimi_wrapper_source.find("for tool in cmake ninja git", + mimi_build_guard) != std::string::npos); + CHECK(mimi_wrapper_source.find("if [[ ! -f \"$MODEL_CONFIG\" ]]", + mimi_build_guard) != std::string::npos); + CHECK(reference_source.find("produced=%d") != std::string::npos); } TEST_CASE("personaplex conversion injects its inference contract") { @@ -162,7 +185,7 @@ TEST_CASE( "personaplex_emel_runner.cpp"); CHECK(std::filesystem::exists(generator_machine)); - CHECK(emel_source.find("emel/speech/generator/sm.hpp") != std::string::npos); + CHECK(emel_source.find("emel/speech/generator/any.hpp") != std::string::npos); CHECK(emel_source.find("speech/generator/moshi/personaplex/session") == std::string::npos); } diff --git a/tools/bench/speech/moshi_reference_driver.cpp b/tools/bench/speech/moshi_reference_driver.cpp index 7aee2534..5e4994ee 100644 --- a/tools/bench/speech/moshi_reference_driver.cpp +++ b/tools/bench/speech/moshi_reference_driver.cpp @@ -312,18 +312,21 @@ int run_personaplex(const options &opts, ggml_backend_t backend_cpu) { moshi_lm_send2(generator, tokens); const int produced = moshi_lm_receive(generator, text_token, tokens); + std::printf("output frame=%d produced=%d text=%d codes=", frame, produced, + produced != 0 ? text_token : -1); + for (size_t stream = 0; stream < tokens.size(); ++stream) { + std::printf("%s%d", stream == 0u ? "" : ",", + produced != 0 ? static_cast(tokens[stream]) : -1); + } + std::printf("\n"); if (produced != 0) { - std::printf("output frame=%d text=%d codes=", frame, text_token); - for (size_t stream = 0; stream < tokens.size(); ++stream) { - std::printf("%s%d", stream == 0u ? "" : ",", - static_cast(tokens[stream])); - } - std::printf("\n"); mimi_decode_send(decoder, tokens.data()); mimi_decode_receive(decoder, decoded_frame.data()); - output_pcm.insert(output_pcm.end(), decoded_frame.begin(), - decoded_frame.end()); + } else { + std::fill(decoded_frame.begin(), decoded_frame.end(), 0.0f); } + output_pcm.insert(output_pcm.end(), decoded_frame.begin(), + decoded_frame.end()); } const double elapsed = std::chrono::duration(std::chrono::steady_clock::now() - started) From ed9a5489901e915869dcc8450f2cb110e5ba5088 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 09:52:57 -0500 Subject: [PATCH 49/61] fix Moshi executor guard bounds --- .../predictor/moshi/executor/detail.hpp | 3 +- .../predictor/moshi/executor/guards.hpp | 69 +++++--- .../predictor/moshi_lifecycle_tests.cpp | 166 ++++++++++++++++++ 3 files changed, 209 insertions(+), 29 deletions(-) diff --git a/src/emel/speech/predictor/moshi/executor/detail.hpp b/src/emel/speech/predictor/moshi/executor/detail.hpp index e06a4b6c..796a1233 100644 --- a/src/emel/speech/predictor/moshi/executor/detail.hpp +++ b/src/emel/speech/predictor/moshi/executor/detail.hpp @@ -183,7 +183,8 @@ inline bool tensor_shape(const tensor_record *tensor, const int64_t ne0, const int64_t ne1 = 1) noexcept { return tensor != nullptr && tensor->data != nullptr && tensor->n_dims >= 1 && tensor->dims[0] == ne0 && - (tensor->n_dims == 1 || tensor->dims[1] == ne1); + ((tensor->n_dims == 1 && ne1 == 1) || + (tensor->n_dims >= 2 && tensor->dims[1] == ne1)); } inline bool token_in_embedding_range(const int32_t token, const int32_t card, diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 0dc53926..d1c99fa0 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -11,6 +11,29 @@ namespace emel::speech::predictor::moshi::executor::guard { +inline bool guard_cache_span_valid(const size_t layer_offset, + const size_t first_position, + const size_t position_count, + const size_t dim, + const size_t key_cache_size, + const size_t value_cache_size) noexcept { + if (dim == 0u || first_position > + std::numeric_limits::max() / dim || + position_count > std::numeric_limits::max() / dim) { + return false; + } + const size_t first_element = first_position * dim; + const size_t element_count = position_count * dim; + if (layer_offset > + std::numeric_limits::max() - first_element) { + return false; + } + const size_t begin = layer_offset + first_element; + return begin <= key_cache_size && begin <= value_cache_size && + element_count <= key_cache_size - begin && + element_count <= value_cache_size - begin; +} + struct guard_bind_contract_valid { bool operator()(const event::initialize_run &runtime_ev, const action::context &ctx) const noexcept { @@ -838,15 +861,14 @@ struct guard_temporal_layer_cache_write_supported { runtime_ev.ctx.temporal_position.physical_position < 0) { return false; } - const size_t layer_offset = - view.layer_cache_offsets[static_cast(layer)]; const size_t physical_position = static_cast(runtime_ev.ctx.temporal_position.physical_position); const size_t dim = static_cast(hidden_dim); - const size_t begin = layer_offset + physical_position * dim; - const size_t end = begin + dim; return physical_position < static_cast(view.position_capacity) && - end <= view.key_cache.size() && end <= view.value_cache.size(); + guard_cache_span_valid( + view.layer_cache_offsets[static_cast(layer)], + physical_position, 1u, dim, view.key_cache.size(), + view.value_cache.size()); } }; @@ -898,8 +920,9 @@ struct guard_temporal_layer_attention_supported { const size_t layer_offset = view.layer_cache_offsets[static_cast(layer)]; const size_t dim = static_cast(hidden_dim); - const size_t end = layer_offset + static_cast(capacity) * dim; - return end <= view.key_cache.size() && end <= view.value_cache.size(); + return guard_cache_span_valid( + layer_offset, 0u, static_cast(capacity), dim, + view.key_cache.size(), view.value_cache.size()); } }; @@ -1221,12 +1244,10 @@ struct guard_text_logits_unsupported { struct guard_forced_text_token_valid { bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { + const action::context &) const noexcept { return runtime_ev.request.forced_text_token >= 0 && - detail::token_in_embedding_range( - runtime_ev.request.forced_text_token, - runtime_ev.request.model.moshi_lm.text_card, - ctx.policy.token_zero); + runtime_ev.request.forced_text_token < + runtime_ev.request.model.moshi_lm.text_card; } }; @@ -1716,12 +1737,10 @@ struct guard_depformer_layer_cache_write_supported { physical >= view.position_capacity) { return false; } - const size_t layer_offset = - view.layer_cache_offsets[static_cast(layer)]; - const size_t begin = layer_offset + static_cast(physical) * - static_cast(dep_dim); - const size_t end = begin + static_cast(dep_dim); - return end <= view.key_cache.size() && end <= view.value_cache.size(); + return guard_cache_span_valid( + view.layer_cache_offsets[static_cast(layer)], + static_cast(physical), 1u, static_cast(dep_dim), + view.key_cache.size(), view.value_cache.size()); } }; @@ -1773,17 +1792,11 @@ struct guard_depformer_layer_attention_supported { static_cast(layer) >= view.layer_cache_offsets.size()) { return false; } - const size_t layer_offset = - view.layer_cache_offsets[static_cast(layer)]; const size_t dim = static_cast(dep_dim); - for (int32_t physical = 0; physical < capacity; ++physical) { - const size_t begin = layer_offset + static_cast(physical) * dim; - const size_t end = begin + dim; - if (end > view.key_cache.size() || end > view.value_cache.size()) { - return false; - } - } - return true; + return guard_cache_span_valid( + view.layer_cache_offsets[static_cast(layer)], 0u, + static_cast(capacity), dim, view.key_cache.size(), + view.value_cache.size()); } }; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 4b3e296e..4dc066d0 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -2206,6 +2206,172 @@ TEST_CASE("speech_moshi_executor_generates_audio_tokens_with_injected_kv") { [](const uint16_t value) { return value != 0u; })); } +TEST_CASE( + "speech_moshi_executor_guards_reject_invalid_outputs_and_cache_metadata") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + const auto &lm = fixture.model->moshi_lm; + + emel::kernel::sm kernel{}; + moshi_executor::action::context executor_ctx{ + make_executor_dependencies(kernel)}; + executor_ctx.session.hidden_dim = lm.dim; + executor_ctx.session.text_card = lm.text_card; + + emel::memory::view::snapshot snapshot{}; + std::array input = {}; + std::array output = {}; + int32_t text_token = -1; + moshi::event::graph_step step{ + *fixture.model, snapshot, + std::span{input.data(), static_cast(lm.n_q + 1)}, + std::span{output.data(), static_cast(lm.dep_q)}, + text_token}; + auto step_ctx = std::make_unique(); + moshi_executor::event::step_run step_run{step, *step_ctx}; + + step.forced_text_token = lm.text_card; + CHECK_FALSE(moshi_executor::guard::guard_forced_text_token_valid{}( + step_run, executor_ctx)); + + float tensor_data = 0.0f; + emel::model::data::tensor_record malformed_matrix{}; + malformed_matrix.data = &tensor_data; + malformed_matrix.n_dims = 1; + malformed_matrix.dims[0] = lm.dim; + CHECK_FALSE(moshi_executor::detail::tensor_shape(&malformed_matrix, lm.dim, + lm.dim * 3)); + + std::array key_cache = + {}; + std::array value_cache = + {}; + std::array offsets = {std::numeric_limits::max()}; + step_ctx->temporal_layer_rope_ok = true; + step_ctx->temporal_layer_index = 0; + step_ctx->temporal_position.physical_position = 0; + step_ctx->temporal_kv = moshi_executor::detail::temporal_kv_view{ + .key_cache = key_cache, + .value_cache = value_cache, + .layer_cache_offsets = offsets, + .layer_count = 1, + .position_capacity = 1, + .kv_dim = lm.dim, + }; + CHECK_FALSE( + moshi_executor::guard::guard_temporal_layer_cache_write_supported{}( + step_run, executor_ctx)); + + step_ctx->depformer_layer_projection_ok = true; + step_ctx->depformer_layer_index = 0; + step_ctx->depformer_position.physical_position = 0; + step_ctx->depformer_kv = moshi_executor::detail::depformer_kv_view{ + .key_cache = key_cache, + .value_cache = value_cache, + .layer_cache_offsets = offsets, + .layer_count = 1, + .position_capacity = 1, + .kv_dim = lm.depformer_dim, + }; + CHECK_FALSE( + moshi_executor::guard::guard_depformer_layer_cache_write_supported{}( + step_run, executor_ctx)); + + CHECK_FALSE(moshi_executor::guard::guard_cache_span_valid( + 0u, std::numeric_limits::max(), 1u, 2u, key_cache.size(), + value_cache.size())); + CHECK_FALSE(moshi_executor::guard::guard_cache_span_valid( + std::numeric_limits::max(), 1u, 1u, 1u, key_cache.size(), + value_cache.size())); + CHECK(moshi_executor::guard::guard_sampling_step_invalid{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_sampling_step_valid{}(step_run, + executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_position_advance_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_position_advance_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_norm2_unsupported{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_norm2_supported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_norm2_rms_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_norm2_rms_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_norm2_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_norm2_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_gating_in_unsupported{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_gating_in_supported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_gating_in_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_gating_in_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_silu_gate_unsupported{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_silu_gate_supported{}( + step_run, executor_ctx)); + CHECK( + moshi_executor::guard::guard_temporal_layer_silu_gate_silu_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_silu_gate_silu_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_silu_gate_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_silu_gate_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_gating_out_unsupported{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_gating_out_supported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_gating_out_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_gating_out_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_ff_residual_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_ff_residual_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_out_norm_unsupported{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_out_norm_supported{}( + step_run, executor_ctx)); + step_ctx->temporal_layer_index = lm.num_layers; + step_ctx->temporal_layer_ff_residual_ok = true; + CHECK(moshi_executor::guard::guard_temporal_out_norm_supported{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_out_norm_rms_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_out_norm_rms_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_out_norm_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_out_norm_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_text_logits_unsupported{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_text_logits_supported{}(step_run, + executor_ctx)); + CHECK(moshi_executor::guard::guard_text_logits_matmul_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_text_logits_matmul_succeeded{}( + step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_text_logits_failed{}(step_run, + executor_ctx) != + moshi_executor::guard::guard_text_logits_succeeded{}(step_run, + executor_ctx)); + CHECK(moshi_executor::guard::guard_text_sampling_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_text_sampling_succeeded{}(step_run, + executor_ctx)); +} + TEST_CASE("speech_moshi_executor_sampling_rng_is_actor_owned") { auto first_fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); auto second_fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); From 033f4afc14d30d5c67d9b6c2f7b5ffed960390c1 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 10:05:38 -0500 Subject: [PATCH 50/61] reset Moshi executor streaming actors --- snapshots/lint/clang_format.txt | 1 + .../predictor/moshi/executor/actions.hpp | 34 +++++++++- .../predictor/moshi/executor/errors.hpp | 1 + .../predictor/moshi/executor/events.hpp | 13 ++++ .../predictor/moshi/executor/guards.hpp | 62 +++++++++++++++++++ .../speech/predictor/moshi/executor/sm.hpp | 57 +++++++++++++++-- .../moshi_executor_streaming_tests.cpp | 10 +++ 7 files changed, 172 insertions(+), 6 deletions(-) diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index eb8df14a..d4b46ca4 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -605,6 +605,7 @@ tests/memory/kv/lifecycle_tests.cpp tests/memory/recurrent/lifecycle_tests.cpp tests/model/fixture_manifest_tests.cpp tests/model/loader/lifecycle_tests.cpp +tests/model/moshi/binding_tests.cpp tests/model/tensor/lifecycle_tests.cpp tests/model/tensor/window/lifecycle_tests.cpp tests/model/tensor/window/streaming_tests.cpp diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index ecd7ae68..066a2ad9 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -1107,6 +1107,7 @@ struct effect_reset_depformer_positions { emel::memory::streaming::event::reset{ .error_out = runtime_ev.ctx.depformer_position_error}); } + }; struct effect_advance_depformer_position { @@ -1929,11 +1930,42 @@ struct effect_emit_initialize_error { }; struct effect_reset_session { - void operator()(const event::reset &, context &ctx) const noexcept { + void operator()(const event::reset_run &, context &ctx) const noexcept { ctx.session = {}; } }; +struct effect_reset_temporal_positions { + void operator()(const event::reset_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.temporal_position_error = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.temporal_position_accepted = + ctx.temporal_positions->process_event( + emel::memory::streaming::event::reset{ + .error_out = runtime_ev.ctx.temporal_position_error}); + } +}; + +struct effect_reset_bound_depformer_positions { + void operator()(const event::reset_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.depformer_position_error = static_cast( + emel::error::cast(emel::memory::streaming::error::none)); + runtime_ev.ctx.depformer_position_accepted = + ctx.depformer_positions->process_event( + emel::memory::streaming::event::reset{ + .error_out = runtime_ev.ctx.depformer_position_error}); + } +}; + +struct effect_mark_reset_failed { + void operator()(const event::reset_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::reset_failed); + } +}; + struct effect_mark_unexpected { template void operator()(const unexpected_event_type &ev, context &) const noexcept { diff --git a/src/emel/speech/predictor/moshi/executor/errors.hpp b/src/emel/speech/predictor/moshi/executor/errors.hpp index 57eee8a4..663c73fe 100644 --- a/src/emel/speech/predictor/moshi/executor/errors.hpp +++ b/src/emel/speech/predictor/moshi/executor/errors.hpp @@ -12,6 +12,7 @@ enum class error : emel::error::type { model_mismatch = 4, graph_execution_unsupported = 5, unexpected_event = 6, + reset_failed = 7, }; } // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/predictor/moshi/executor/events.hpp b/src/emel/speech/predictor/moshi/executor/events.hpp index 8f4115ca..737c118c 100644 --- a/src/emel/speech/predictor/moshi/executor/events.hpp +++ b/src/emel/speech/predictor/moshi/executor/events.hpp @@ -146,6 +146,19 @@ struct step_run { struct reset {}; +struct reset_ctx { + emel::error::type err = emel::error::cast(error::none); + bool temporal_position_accepted = false; + bool depformer_position_accepted = false; + int32_t temporal_position_error = 0; + int32_t depformer_position_error = 0; +}; + +struct reset_run { + const reset &request; + reset_ctx &ctx; +}; + } // namespace emel::speech::predictor::moshi::executor::event namespace emel::speech::predictor::moshi::executor::events { diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index d1c99fa0..078097e8 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -2214,6 +2214,68 @@ struct guard_depformer_logits_matmul_failed { } }; +struct guard_reset_temporal_positions_present { + bool operator()(const event::reset_run &, + const action::context &ctx) const noexcept { + return ctx.temporal_positions != nullptr; + } +}; + +struct guard_reset_temporal_positions_missing { + bool operator()(const event::reset_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_reset_temporal_positions_present{}(runtime_ev, ctx); + } +}; + +struct guard_reset_temporal_positions_succeeded { + bool operator()(const event::reset_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.temporal_position_accepted && + runtime_ev.ctx.temporal_position_error == + static_cast(emel::error::cast( + emel::memory::streaming::error::none)); + } +}; + +struct guard_reset_temporal_positions_failed { + bool operator()(const event::reset_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_reset_temporal_positions_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_reset_depformer_positions_present { + bool operator()(const event::reset_run &, + const action::context &ctx) const noexcept { + return ctx.depformer_positions != nullptr; + } +}; + +struct guard_reset_depformer_positions_missing { + bool operator()(const event::reset_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_reset_depformer_positions_present{}(runtime_ev, ctx); + } +}; + +struct guard_reset_depformer_positions_succeeded { + bool operator()(const event::reset_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.depformer_position_accepted && + runtime_ev.ctx.depformer_position_error == + static_cast(emel::error::cast( + emel::memory::streaming::error::none)); + } +}; + +struct guard_reset_depformer_positions_failed { + bool operator()(const event::reset_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_reset_depformer_positions_succeeded{}(runtime_ev, ctx); + } +}; + struct guard_more_depformer_codebooks { bool operator()(const event::step_run &runtime_ev, const action::context &) const noexcept { diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index 1563aa05..fc1320a0 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -12,6 +12,11 @@ namespace emel::speech::predictor::moshi::executor { struct state_uninitialized {}; +struct state_reset_temporal_positions_decision {}; +struct state_reset_temporal_positions_result_decision {}; +struct state_reset_depformer_positions_decision {}; +struct state_reset_depformer_positions_result_decision {}; +struct state_reset_failed {}; struct state_bind_contract_decision {}; struct state_input_embedding_contract_decision {}; struct state_temporal_projection_layout_decision {}; @@ -169,6 +174,7 @@ struct state_uninit_step_error_out_decision {}; struct model { auto operator()() const { namespace sml = stateforward::sml; + using reset_run = event::reset_run; using init_run = event::initialize_run; using step_run = event::step_run; @@ -1013,12 +1019,50 @@ struct model { //------------------------------------------------------------------------------// // Reset. - , sml::state <= sml::state - + sml::event + , sml::state <= sml::state + + sml::event + , sml::state <= sml::state + + sml::event + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_temporal_positions_present{} ] + / action::effect_reset_temporal_positions{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_temporal_positions_missing{} ] + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_temporal_positions_succeeded{} ] + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_temporal_positions_failed{} ] + / action::effect_mark_reset_failed{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_depformer_positions_present{} ] + / action::effect_reset_bound_depformer_positions{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_depformer_positions_missing{} ] / action::effect_reset_session{} - , sml::state <= sml::state - + sml::event + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_depformer_positions_succeeded{} ] / action::effect_reset_session{} + , sml::state <= + sml::state + + sml::completion + [ guard::guard_reset_depformer_positions_failed{} ] + / action::effect_mark_reset_failed{} + , sml::state <= sml::state + + sml::completion / action::effect_reset_session{} //------------------------------------------------------------------------------// // Unexpected events. @@ -1090,7 +1134,10 @@ struct sm : public emel::sm { } bool process_event(const event::reset &ev) { - return base_type::process_event(ev); + event::reset_ctx ctx{}; + event::reset_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); } }; diff --git a/tests/speech/predictor/moshi_executor_streaming_tests.cpp b/tests/speech/predictor/moshi_executor_streaming_tests.cpp index fa2a8d35..3a05f84f 100644 --- a/tests/speech/predictor/moshi_executor_streaming_tests.cpp +++ b/tests/speech/predictor/moshi_executor_streaming_tests.cpp @@ -159,4 +159,14 @@ TEST_CASE( step.phase = moshi::event::graph_phase::sampling; REQUIRE(machine.process_event(step)); CHECK(capture(depformer_positions).logical_end == lm.dep_q); + + REQUIRE(machine.process_event(executor::event::reset{})); + CHECK(capture(temporal_positions).logical_end == 0); + CHECK(capture(depformer_positions).logical_end == 0); + CHECK(machine.is(stateforward::sml::state)); + + REQUIRE(machine.process_event(initialize)); + step.phase = moshi::event::graph_phase::prediction; + REQUIRE(machine.process_event(step)); + CHECK(capture(temporal_positions).logical_end == 1); } From 31ea6add7072bdf0b53c82aeefc823a76396a364 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 10:15:13 -0500 Subject: [PATCH 51/61] validate Moshi prompt before allocation --- src/emel/speech/predictor/moshi/guards.hpp | 23 +++++++++++++++---- .../predictor/moshi_lifecycle_tests.cpp | 12 ++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index ad122f83..877edd72 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -378,15 +378,30 @@ struct guard_personaplex_prompt_begin_invalid { } }; +struct guard_personaplex_prompt_current_phase_valid { + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, + const action::context &ctx) const noexcept { + return ctx.voice.pre_text_silence_remaining > 0 || + (ctx.voice.pre_text_silence_remaining == 0 && + ctx.voice.text_tokens_remaining > 0 && + runtime_ev.request.text_token >= 0 && + runtime_ev.request.text_token < ctx.session.text_card) || + (ctx.voice.pre_text_silence_remaining == 0 && + ctx.voice.text_tokens_remaining == 0 && + ctx.voice.post_text_silence_remaining > 0); + } +}; + struct guard_personaplex_prompt_prefill_request_valid { - bool operator()(const event::prefill_personaplex_prompt_run &, + bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, const action::context &ctx) const noexcept { const int32_t frame_count = ctx.voice.pre_text_silence_remaining + ctx.voice.text_tokens_remaining + ctx.voice.post_text_silence_remaining; return ctx.session.model != nullptr && ctx.voice.loaded && ctx.voice.ready && ctx.voice.prompt_started && - !ctx.voice.prompt_ready && frame_count > 0; + !ctx.voice.prompt_ready && frame_count > 0 && + guard_personaplex_prompt_current_phase_valid{}(runtime_ev, ctx); } }; @@ -426,9 +441,7 @@ struct guard_personaplex_prompt_post_silence_pending { struct guard_personaplex_prompt_phase_invalid { bool operator()(const event::prefill_personaplex_prompt_run &runtime_ev, const action::context &ctx) const noexcept { - return !guard_personaplex_prompt_pre_silence_pending{}(runtime_ev, ctx) && - !guard_personaplex_prompt_text_pending{}(runtime_ev, ctx) && - !guard_personaplex_prompt_post_silence_pending{}(runtime_ev, ctx); + return !guard_personaplex_prompt_current_phase_valid{}(runtime_ev, ctx); } }; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 4dc066d0..be7b7040 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -669,6 +669,18 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" const std::array prompt_text_tokens = {-1, 42, 43, -1}; const std::array expected_text_inputs = {3, 42, 43, 3}; for (int32_t index = 0; index < 4; ++index) { + if (index == 1) { + const int32_t allocations_before = kv.allocate_slots_count; + const int32_t graph_calls_before = graph.call_count; + moshi::event::prefill_personaplex_prompt invalid_prefill{}; + invalid_prefill.text_token = fixture.model->moshi_lm.text_card; + invalid_prefill.error_out = &err; + err = k_no_error; + CHECK_FALSE(generator.process_event(invalid_prefill)); + CHECK(err == emel::error::cast(moshi::error::personaplex_prompt)); + CHECK(kv.allocate_slots_count == allocations_before); + CHECK(graph.call_count == graph_calls_before); + } bool complete = true; int32_t remaining = -1; emel::error::type graph_err = emel::error::cast(moshi::error::none); From 7d89376a5a1820c20ef41d20820465a2833bc547 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 10:20:56 -0500 Subject: [PATCH 52/61] reset Moshi predictor child actors --- src/emel/speech/predictor/moshi/actions.hpp | 35 +++++++++++++++++ src/emel/speech/predictor/moshi/events.hpp | 7 ++++ .../speech/predictor/moshi/executor/sm.hpp | 5 +++ src/emel/speech/predictor/moshi/guards.hpp | 31 +++++++++++++++ src/emel/speech/predictor/moshi/sm.hpp | 38 ++++++++++++++----- .../predictor/moshi_lifecycle_tests.cpp | 20 ++++++++++ 6 files changed, 126 insertions(+), 10 deletions(-) diff --git a/src/emel/speech/predictor/moshi/actions.hpp b/src/emel/speech/predictor/moshi/actions.hpp index cfae8713..3a77895c 100644 --- a/src/emel/speech/predictor/moshi/actions.hpp +++ b/src/emel/speech/predictor/moshi/actions.hpp @@ -768,6 +768,41 @@ struct effect_reset_session { } }; +template struct effect_reset_graph { + void operator()(const event::reset_run &runtime_ev, context &, + graph_actor_type &graph) const noexcept { + runtime_ev.ctx.graph_error = detail_ns::to_error(error::none); + runtime_ev.ctx.graph_accepted = graph.process_event(runtime_ev.request); + } +}; + +struct effect_release_reset_sequence { + void operator()(const event::reset_run &runtime_ev, + context &ctx) const noexcept { + runtime_ev.ctx.memory_error = static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + runtime_ev.ctx.memory_accepted = + ctx.memory.process_event(emel::memory::event::free_sequence{ + .seq_id = ctx.session.sequence_id, + .error_out = &runtime_ev.ctx.memory_error, + }); + } +}; + +struct effect_mark_reset_graph_failed { + void operator()(const event::reset_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::graph_runtime); + } +}; + +struct effect_mark_reset_memory_failed { + void operator()(const event::reset_run &runtime_ev, + context &) const noexcept { + runtime_ev.ctx.err = detail_ns::to_error(error::memory); + } +}; + template struct effect_store_error_out { void operator()(const runtime_event_type &runtime_ev, context &) const noexcept { diff --git a/src/emel/speech/predictor/moshi/events.hpp b/src/emel/speech/predictor/moshi/events.hpp index 30ddd58d..b914e937 100644 --- a/src/emel/speech/predictor/moshi/events.hpp +++ b/src/emel/speech/predictor/moshi/events.hpp @@ -322,6 +322,13 @@ struct sample_run { struct reset_run { const reset &request; + struct context { + emel::error::type err = emel::error::cast(error::none); + bool graph_accepted = false; + emel::error::type graph_error = emel::error::cast(error::none); + bool memory_accepted = false; + int32_t memory_error = static_cast(emel::error::cast(error::none)); + } &ctx; }; } // namespace emel::speech::predictor::moshi::event diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index fc1320a0..a3bd2a0e 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -1139,6 +1139,11 @@ struct sm : public emel::sm { const bool accepted = base_type::process_event(runtime_ev); return accepted && ctx.err == action::detail_ns::to_error(error::none); } + + bool process_event( + const emel::speech::predictor::moshi::event::reset &) { + return process_event(event::reset{}); + } }; } // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 877edd72..369bcdf4 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -445,6 +445,37 @@ struct guard_personaplex_prompt_phase_invalid { } }; +struct guard_reset_graph_succeeded { + bool operator()(const event::reset_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.graph_accepted; + } +}; + +struct guard_reset_graph_failed { + bool operator()(const event::reset_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_reset_graph_succeeded{}(runtime_ev, ctx); + } +}; + +struct guard_reset_memory_succeeded { + bool operator()(const event::reset_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.ctx.memory_accepted && + runtime_ev.ctx.memory_error == + static_cast( + emel::error::cast(emel::memory::hybrid::error::none)); + } +}; + +struct guard_reset_memory_failed { + bool operator()(const event::reset_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_reset_memory_succeeded{}(runtime_ev, ctx); + } +}; + struct guard_personaplex_prompt_complete { bool operator()(const event::prefill_personaplex_prompt_run &, const action::context &ctx) const noexcept { diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 1408bc66..51353609 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -14,6 +14,9 @@ namespace emel::speech::predictor::moshi { struct state_uninitialized {}; +struct state_reset_graph_result_decision {}; +struct state_reset_memory_result_decision {}; +struct state_reset_failed {}; struct state_bind_contract_decision {}; struct state_binding {}; struct state_lmgen_mode_decision {}; @@ -126,6 +129,7 @@ template struct model { using predict_run = event::predict_run; using execute_run = event::execute_run; using sample_run = event::sample_run; + using reset_run = event::reset_run; // clang-format off return sml::make_transition_table( @@ -706,15 +710,27 @@ template struct model { //------------------------------------------------------------------------------// // Reset. - , sml::state <= sml::state - + sml::event - / action::effect_reset_session{} - , sml::state <= sml::state - + sml::event - / action::effect_reset_session{} - , sml::state <= sml::state - + sml::event + , sml::state <= sml::state + + sml::event / action::effect_reset_graph{} + , sml::state <= sml::state + + sml::event / action::effect_reset_graph{} + , sml::state <= sml::state + + sml::event / action::effect_reset_graph{} + , sml::state <= + sml::state + + sml::completion [ guard::guard_reset_graph_succeeded{} ] + / action::effect_release_reset_sequence{} + , sml::state <= sml::state + + sml::completion [ guard::guard_reset_graph_failed{} ] + / action::effect_mark_reset_graph_failed{} + , sml::state <= sml::state + + sml::completion [ guard::guard_reset_memory_succeeded{} ] / action::effect_reset_session{} + , sml::state <= sml::state + + sml::completion [ guard::guard_reset_memory_failed{} ] + / action::effect_mark_reset_memory_failed{} + , sml::state <= sml::state + + sml::completion / action::effect_reset_session{} //------------------------------------------------------------------------------// // Unexpected events. @@ -832,8 +848,10 @@ struct sm : public emel::sm, action::context> { } bool process_event(const event::reset &ev) { - event::reset_run runtime_ev{ev}; - return base_type::process_event(runtime_ev); + event::reset_run::context ctx{}; + event::reset_run runtime_ev{ev, ctx}; + const bool accepted = base_type::process_event(runtime_ev); + return accepted && ctx.err == action::detail_ns::to_error(error::none); } private: diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index be7b7040..de6c3fcc 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -91,6 +91,8 @@ void configure_predictor_initialize(moshi::event::initialize &request) { } struct recording_graph_executor { + bool initialized = false; + int32_t reset_count = 0; int32_t call_count = 0; int32_t external_embedding_count = 0; int32_t first_sequence_length = -1; @@ -103,9 +105,19 @@ struct recording_graph_executor { std::array last_input = {}; bool process_event(const moshi::event::initialize_graph &request) noexcept { + if (initialized) { + *request.error_out = emel::error::cast(moshi::error::graph_runtime); + return false; + } + initialized = true; *request.error_out = k_no_error; return true; } + bool process_event(const moshi::event::reset &) noexcept { + initialized = false; + ++reset_count; + return true; + } bool process_event(const moshi::event::graph_step &step); }; @@ -432,6 +444,14 @@ TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { CHECK(err == k_no_error); CHECK(kv.reserve_count == 1); CHECK(kv.allocate_sequence_count == 1); + + REQUIRE(generator.process_event(moshi::event::reset{})); + CHECK(graph.reset_count == 1); + CHECK(kv.free_sequence_count == 1); + err = k_no_error; + REQUIRE(generator.process_event(init)); + CHECK(err == k_no_error); + CHECK(kv.allocate_sequence_count == 2); } TEST_CASE("speech_moshi_predictor_rejects_missing_initialize_capacity") { From 82039caf31f6f8d80bf242e5b8fd6d48cf8958d7 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 10:33:31 -0500 Subject: [PATCH 53/61] refresh Moshi executor statechart --- .../speech_predictor_moshi_executor.mmd | 13 ++++++++-- .../speech_predictor_moshi_executor.md | 26 ++++++++++++++++--- README.md | 2 +- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd index 2e0604d3..4da0f26d 100644 --- a/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd +++ b/.planning/architecture/mermaid/speech_predictor_moshi_executor.mmd @@ -289,8 +289,17 @@ stateDiagram-v2 state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / effect_mark_not_initialized_ state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / step_run__ state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / none - state_ready --> state_uninitialized : reset [always] / effect_reset_session_ - state_sampling_ready --> state_uninitialized : reset [always] / effect_reset_session_ + state_ready --> state_reset_temporal_positions_decision : reset_run [always] / none + state_sampling_ready --> state_reset_temporal_positions_decision : reset_run [always] / none + state_reset_temporal_positions_decision --> state_reset_temporal_positions_result_decision : completion_reset_run_ [guard_reset_temporal_positions_present_] / effect_reset_temporal_positions_ + state_reset_temporal_positions_decision --> state_reset_depformer_positions_decision : completion_reset_run_ [guard_reset_temporal_positions_missing_] / none + state_reset_temporal_positions_result_decision --> state_reset_depformer_positions_decision : completion_reset_run_ [guard_reset_temporal_positions_succeeded_] / none + state_reset_temporal_positions_result_decision --> state_reset_failed : completion_reset_run_ [guard_reset_temporal_positions_failed_] / effect_mark_reset_failed_ + state_reset_depformer_positions_decision --> state_reset_depformer_positions_result_decision : completion_reset_run_ [guard_reset_depformer_positions_present_] / effect_reset_bound_depformer_positions_ + state_reset_depformer_positions_decision --> state_uninitialized : completion_reset_run_ [guard_reset_depformer_positions_missing_] / effect_reset_session_ + state_reset_depformer_positions_result_decision --> state_uninitialized : completion_reset_run_ [guard_reset_depformer_positions_succeeded_] / effect_reset_session_ + state_reset_depformer_positions_result_decision --> state_reset_failed : completion_reset_run_ [guard_reset_depformer_positions_failed_] / effect_mark_reset_failed_ + state_reset_failed --> state_uninitialized : completion_reset_run_ [always] / effect_reset_session_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ state_ready --> state_ready : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ diff --git a/.planning/architecture/speech_predictor_moshi_executor.md b/.planning/architecture/speech_predictor_moshi_executor.md index 73f64451..6008b89d 100644 --- a/.planning/architecture/speech_predictor_moshi_executor.md +++ b/.planning/architecture/speech_predictor_moshi_executor.md @@ -296,8 +296,17 @@ stateDiagram-v2 state_uninitialized --> state_uninit_step_error_out_decision : step_run [always] / effect_mark_not_initialized_ state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / step_run__ state_uninit_step_error_out_decision --> state_uninitialized : completion_step_run_ [step_run__] / none - state_ready --> state_uninitialized : reset [always] / effect_reset_session_ - state_sampling_ready --> state_uninitialized : reset [always] / effect_reset_session_ + state_ready --> state_reset_temporal_positions_decision : reset_run [always] / none + state_sampling_ready --> state_reset_temporal_positions_decision : reset_run [always] / none + state_reset_temporal_positions_decision --> state_reset_temporal_positions_result_decision : completion_reset_run_ [guard_reset_temporal_positions_present_] / effect_reset_temporal_positions_ + state_reset_temporal_positions_decision --> state_reset_depformer_positions_decision : completion_reset_run_ [guard_reset_temporal_positions_missing_] / none + state_reset_temporal_positions_result_decision --> state_reset_depformer_positions_decision : completion_reset_run_ [guard_reset_temporal_positions_succeeded_] / none + state_reset_temporal_positions_result_decision --> state_reset_failed : completion_reset_run_ [guard_reset_temporal_positions_failed_] / effect_mark_reset_failed_ + state_reset_depformer_positions_decision --> state_reset_depformer_positions_result_decision : completion_reset_run_ [guard_reset_depformer_positions_present_] / effect_reset_bound_depformer_positions_ + state_reset_depformer_positions_decision --> state_uninitialized : completion_reset_run_ [guard_reset_depformer_positions_missing_] / effect_reset_session_ + state_reset_depformer_positions_result_decision --> state_uninitialized : completion_reset_run_ [guard_reset_depformer_positions_succeeded_] / effect_reset_session_ + state_reset_depformer_positions_result_decision --> state_reset_failed : completion_reset_run_ [guard_reset_depformer_positions_failed_] / effect_mark_reset_failed_ + state_reset_failed --> state_uninitialized : completion_reset_run_ [always] / effect_reset_session_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ state_uninitialized --> state_uninitialized : _ [guard_unexpected_error_out_absent_] / effect_mark_unexpected_ state_ready --> state_ready : _ [guard_unexpected_error_out_present_] / effect_mark_unexpected_and_store_ @@ -598,8 +607,17 @@ stateDiagram-v2 | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_not_initialized>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_uninit_step_error_out_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`step_run>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | -| [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`reset_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_temporal_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_sampling_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`reset_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_temporal_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_temporal_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_temporal_positions_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_temporal_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_temporal_positions_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_temporal_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_temporal_positions_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_depformer_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_temporal_positions_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_temporal_positions_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`none`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_depformer_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_temporal_positions_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_temporal_positions_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_reset_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_depformer_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_depformer_positions_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_bound_depformer_positions>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_depformer_positions_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_depformer_positions_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_depformer_positions_missing>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_depformer_positions_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_depformer_positions_succeeded>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_depformer_positions_result_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_reset_depformer_positions_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_reset_failed>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_reset_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | +| [`state_reset_failed`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_reset_session>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_absent>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`guard_unexpected_error_out_present>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`effect_mark_unexpected_and_store>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/predictor/moshi/executor/sm.hpp) | diff --git a/README.md b/README.md index eed889af..acfdc401 100644 --- a/README.md +++ b/README.md @@ -257,4 +257,4 @@ Generated from `scripts/embedded_size.sh --snapshot-update` using final dead-str - Ratio (`emel / reference`) stripped: `1.457x` - Ratio (`emel / reference`) section: `0.428x` -This is a matched Qwen3-0.6B end-to-end runner size measurement for the maintained `hello` -> first-token path, not a whole-product feature-parity claim. Both binaries still include the platform runtime selected by the toolchain. +This is a matched Qwen3-0.6B end-to-end runner size measurement for the maintained `hello` -> first-token path, not a whole-product feature-parity claim. Both binaries still include the platform runtime selected by the toolchain. \ No newline at end of file From 77df22f64b4628744a04f467bd552e2415341108 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 10:56:38 -0500 Subject: [PATCH 54/61] fix remaining Moshi review findings --- .../mermaid/speech_tokenizer_moshi.mmd | 12 +- .../architecture/speech_tokenizer_moshi.md | 24 +++- snapshots/lint/clang_format.txt | 5 - src/emel/speech/generator/actions.hpp | 2 +- src/emel/speech/generator/context.hpp | 1 + .../predictor/moshi/executor/actions.hpp | 10 +- .../speech/predictor/moshi/executor/sm.hpp | 14 ++- src/emel/speech/predictor/moshi/guards.hpp | 13 ++- src/emel/speech/tokenizer/moshi/guards.hpp | 25 +++- src/emel/speech/tokenizer/moshi/sm.hpp | 40 ++++++- tests/speech/generator/lifecycle_tests.cpp | 5 + .../predictor/moshi_lifecycle_tests.cpp | 107 +++++++++++------- .../tokenizer/moshi/lifecycle_tests.cpp | 42 ++++++- .../bench/speech/personaplex_emel_runner.cpp | 9 ++ 14 files changed, 234 insertions(+), 75 deletions(-) diff --git a/.planning/architecture/mermaid/speech_tokenizer_moshi.mmd b/.planning/architecture/mermaid/speech_tokenizer_moshi.mmd index b74fc882..3281e4e8 100644 --- a/.planning/architecture/mermaid/speech_tokenizer_moshi.mmd +++ b/.planning/architecture/mermaid/speech_tokenizer_moshi.mmd @@ -6,23 +6,29 @@ stateDiagram-v2 state_ready --> state_ready : initialize [always] / already_initialized__ state_prepared_full --> state_prepared_full : initialize [always] / already_initialized__ state_prepared_generated --> state_prepared_generated : initialize [always] / already_initialized__ + state_prepared_tail --> state_prepared_tail : initialize [always] / already_initialized__ state_errored --> state_ready : initialize [guard_configuration_valid_] / effect_initialize_ state_errored --> state_errored : initialize [guard_configuration_invalid_] / invalid_configuration__ state_ready --> state_prepared_full : tokenize [guard_tokenize_full_] / effect_tokenize_full_ - state_ready --> state_prepared_generated : tokenize [guard_tokenize_tail_] / effect_tokenize_tail_ + state_ready --> state_prepared_tail : tokenize [guard_tokenize_tail_] / effect_tokenize_tail_ state_ready --> state_prepared_generated : tokenize [guard_tokenize_empty_] / effect_tokenize_empty_ state_ready --> state_ready : tokenize [guard_tokenize_invalid_] / request_shape__ state_ready --> state_ready : tokenize [guard_tokenize_position_overflow_] / position_overflow__ state_prepared_full --> state_prepared_full : tokenize [always] / phase_order__ state_prepared_generated --> state_prepared_generated : tokenize [always] / phase_order__ + state_prepared_tail --> state_prepared_tail : tokenize [always] / phase_order__ state_prepared_full --> state_commit_full_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ state_prepared_full --> state_commit_full_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ + state_prepared_tail --> state_commit_full_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ + state_prepared_tail --> state_commit_full_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ state_prepared_generated --> state_commit_generated_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ state_prepared_generated --> state_commit_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ state_prepared_full --> state_prepared_full : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ state_prepared_generated --> state_prepared_generated : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ + state_prepared_tail --> state_prepared_tail : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ state_prepared_full --> state_prepared_full : detokenize_run [guard_position_overflow_] / position_overflow__ state_prepared_generated --> state_prepared_generated : detokenize_run [guard_position_overflow_] / position_overflow__ + state_prepared_tail --> state_prepared_tail : detokenize_run [guard_position_overflow_] / position_overflow__ state_commit_full_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ state_commit_full_generated --> state_output_decision : completion_detokenize_run_ [always] / generated__ state_commit_generated_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ @@ -35,13 +41,16 @@ stateDiagram-v2 state_ready --> state_ready : restore_cache [guard_restore_invalid_] / request_shape__ state_prepared_full --> state_prepared_full : restore_cache [always] / phase_order__ state_prepared_generated --> state_prepared_generated : restore_cache [always] / phase_order__ + state_prepared_tail --> state_prepared_tail : restore_cache [always] / phase_order__ state_prepared_full --> state_ready : advance [guard_advance_position_available_] / effect_advance_ state_prepared_full --> state_prepared_full : advance [guard_advance_position_overflow_] / position_overflow__ state_prepared_generated --> state_prepared_generated : advance [always] / phase_order__ + state_prepared_tail --> state_prepared_tail : advance [always] / phase_order__ state_ready --> state_ready : advance [always] / phase_order__ state_ready --> state_ready : reset [always] / effect_reset_ state_prepared_full --> state_ready : reset [always] / effect_reset_ state_prepared_generated --> state_ready : reset [always] / effect_reset_ + state_prepared_tail --> state_ready : reset [always] / effect_reset_ state_errored --> state_ready : reset [always] / effect_reset_ state_uninitialized --> state_uninitialized : tokenize [always] / uninitialized__ state_uninitialized --> state_uninitialized : detokenize_run [always] / uninitialized__ @@ -57,4 +66,5 @@ stateDiagram-v2 state_ready --> state_errored : _ [always] / effect_unexpected_ state_prepared_full --> state_errored : _ [always] / effect_unexpected_ state_prepared_generated --> state_errored : _ [always] / effect_unexpected_ + state_prepared_tail --> state_errored : _ [always] / effect_unexpected_ state_errored --> state_errored : _ [always] / effect_unexpected_ diff --git a/.planning/architecture/speech_tokenizer_moshi.md b/.planning/architecture/speech_tokenizer_moshi.md index 053d33ab..4d936f23 100644 --- a/.planning/architecture/speech_tokenizer_moshi.md +++ b/.planning/architecture/speech_tokenizer_moshi.md @@ -13,23 +13,29 @@ stateDiagram-v2 state_ready --> state_ready : initialize [always] / already_initialized__ state_prepared_full --> state_prepared_full : initialize [always] / already_initialized__ state_prepared_generated --> state_prepared_generated : initialize [always] / already_initialized__ + state_prepared_tail --> state_prepared_tail : initialize [always] / already_initialized__ state_errored --> state_ready : initialize [guard_configuration_valid_] / effect_initialize_ state_errored --> state_errored : initialize [guard_configuration_invalid_] / invalid_configuration__ state_ready --> state_prepared_full : tokenize [guard_tokenize_full_] / effect_tokenize_full_ - state_ready --> state_prepared_generated : tokenize [guard_tokenize_tail_] / effect_tokenize_tail_ + state_ready --> state_prepared_tail : tokenize [guard_tokenize_tail_] / effect_tokenize_tail_ state_ready --> state_prepared_generated : tokenize [guard_tokenize_empty_] / effect_tokenize_empty_ state_ready --> state_ready : tokenize [guard_tokenize_invalid_] / request_shape__ state_ready --> state_ready : tokenize [guard_tokenize_position_overflow_] / position_overflow__ state_prepared_full --> state_prepared_full : tokenize [always] / phase_order__ state_prepared_generated --> state_prepared_generated : tokenize [always] / phase_order__ + state_prepared_tail --> state_prepared_tail : tokenize [always] / phase_order__ state_prepared_full --> state_commit_full_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ state_prepared_full --> state_commit_full_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ + state_prepared_tail --> state_commit_full_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ + state_prepared_tail --> state_commit_full_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ state_prepared_generated --> state_commit_generated_zero : detokenize_run [guard_detokenize_valid_replace_] / effect_begin_detokenize_ state_prepared_generated --> state_commit_generated : detokenize_run [guard_detokenize_valid_generated_] / effect_begin_detokenize_ state_prepared_full --> state_prepared_full : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ state_prepared_generated --> state_prepared_generated : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ + state_prepared_tail --> state_prepared_tail : detokenize_run [guard_detokenize_shape_invalid_] / request_shape__ state_prepared_full --> state_prepared_full : detokenize_run [guard_position_overflow_] / position_overflow__ state_prepared_generated --> state_prepared_generated : detokenize_run [guard_position_overflow_] / position_overflow__ + state_prepared_tail --> state_prepared_tail : detokenize_run [guard_position_overflow_] / position_overflow__ state_commit_full_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ state_commit_full_generated --> state_output_decision : completion_detokenize_run_ [always] / generated__ state_commit_generated_zero --> state_output_decision : completion_detokenize_run_ [always] / zero__ @@ -42,13 +48,16 @@ stateDiagram-v2 state_ready --> state_ready : restore_cache [guard_restore_invalid_] / request_shape__ state_prepared_full --> state_prepared_full : restore_cache [always] / phase_order__ state_prepared_generated --> state_prepared_generated : restore_cache [always] / phase_order__ + state_prepared_tail --> state_prepared_tail : restore_cache [always] / phase_order__ state_prepared_full --> state_ready : advance [guard_advance_position_available_] / effect_advance_ state_prepared_full --> state_prepared_full : advance [guard_advance_position_overflow_] / position_overflow__ state_prepared_generated --> state_prepared_generated : advance [always] / phase_order__ + state_prepared_tail --> state_prepared_tail : advance [always] / phase_order__ state_ready --> state_ready : advance [always] / phase_order__ state_ready --> state_ready : reset [always] / effect_reset_ state_prepared_full --> state_ready : reset [always] / effect_reset_ state_prepared_generated --> state_ready : reset [always] / effect_reset_ + state_prepared_tail --> state_ready : reset [always] / effect_reset_ state_errored --> state_ready : reset [always] / effect_reset_ state_uninitialized --> state_uninitialized : tokenize [always] / uninitialized__ state_uninitialized --> state_uninitialized : detokenize_run [always] / uninitialized__ @@ -64,6 +73,7 @@ stateDiagram-v2 state_ready --> state_errored : _ [always] / effect_unexpected_ state_prepared_full --> state_errored : _ [always] / effect_unexpected_ state_prepared_generated --> state_errored : _ [always] / effect_unexpected_ + state_prepared_tail --> state_errored : _ [always] / effect_unexpected_ state_errored --> state_errored : _ [always] / effect_unexpected_ ``` @@ -76,23 +86,29 @@ stateDiagram-v2 | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`already_initialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_configuration_valid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_initialize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`initialize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_configuration_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`invalid_configuration>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_full>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_tokenize_full>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | -| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_tail>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_tokenize_tail>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_tail>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_tokenize_tail>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_empty>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_tokenize_empty>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_tokenize_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_replace>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_full_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_full_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_replace>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_full_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_full_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_replace>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_generated_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_valid_generated>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_begin_detokenize>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_commit_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_detokenize_shape_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_commit_full_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`zero>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_commit_full_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`generated>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_commit_generated_zero`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`completion`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`zero>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_output_decision`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | @@ -105,13 +121,16 @@ stateDiagram-v2 | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_restore_invalid>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`request_shape>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`restore_cache`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_advance_position_available>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_advance>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`guard_advance_position_overflow>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`position_overflow>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`advance`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`phase_order>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`reset`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_reset>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`tokenize`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`detokenize_run`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`uninitialized>>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_uninitialized`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | @@ -127,4 +146,5 @@ stateDiagram-v2 | [`state_ready`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_full`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_prepared_generated`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | +| [`state_prepared_tail`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`_`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`always`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`effect_unexpected>`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | [`state_errored`](https://github.com/stateforward/emel.cpp/blob/main/src/emel/speech/tokenizer/moshi/sm.hpp) | diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index b9cfd793..cfe18b94 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -363,10 +363,7 @@ src/emel/speech/encoder/whisper/context.hpp src/emel/speech/encoder/whisper/errors.hpp src/emel/speech/encoder/whisper/guards.hpp src/emel/speech/predictor/moshi/events.hpp -src/emel/speech/predictor/moshi/executor/actions.hpp src/emel/speech/predictor/moshi/executor/guards.hpp -src/emel/speech/predictor/moshi/executor/sm.hpp -src/emel/speech/predictor/moshi/guards.hpp src/emel/tensor/view/actions.hpp src/emel/tensor/view/context.hpp src/emel/tensor/view/detail.hpp @@ -607,8 +604,6 @@ tests/sm/sm_any_tests.cpp tests/sm/sm_external_completion_tests.cpp tests/sm/sm_policy_tests.cpp tests/speech/encoder/whisper/detail_tests.cpp -tests/speech/predictor/moshi_lifecycle_tests.cpp -tests/speech/tokenizer/moshi/lifecycle_tests.cpp tests/speech/tokenizer/whisper_tests.cpp tests/tensor/view/lifecycle_tests.cpp tests/text/conditioner/text_conditioner_tests.cpp diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index 10b1590e..c4d91620 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -243,7 +243,7 @@ template struct effect_begin_prompt_conditioning { void operator()(const event::condition_run &runtime_ev, context &ctx) const noexcept { runtime_ev.ctx.child_err = 0; - typename dependencies_type::prompt_begin_event request{}; + auto request = ctx.collaborators.prompt_begin; request.error_out = &runtime_ev.ctx.child_err; runtime_ev.ctx.child_accepted = ctx.collaborators.predictor.process_event(request); diff --git a/src/emel/speech/generator/context.hpp b/src/emel/speech/generator/context.hpp index 5242aa3f..2819c58a 100644 --- a/src/emel/speech/generator/context.hpp +++ b/src/emel/speech/generator/context.hpp @@ -44,6 +44,7 @@ concept duplex_dependencies = requires(dependencies_type deps) { deps.decoder_initialize; deps.predictor_initialize; deps.conditioning_initialize; + deps.prompt_begin; deps.silence_pcm; deps.input_codes; deps.tokenize_input_codes; diff --git a/src/emel/speech/predictor/moshi/executor/actions.hpp b/src/emel/speech/predictor/moshi/executor/actions.hpp index 066a2ad9..6e59db81 100644 --- a/src/emel/speech/predictor/moshi/executor/actions.hpp +++ b/src/emel/speech/predictor/moshi/executor/actions.hpp @@ -98,10 +98,9 @@ struct effect_bind_depformer_fused_projection_layout { struct effect_bind_nonzero_sampling_seed { void operator()(const event::initialize_run &runtime_ev, context &ctx) const noexcept { - ctx.sampling.random_state = - ((runtime_ev.request.sampling_seed - 1u) % - (ctx.policy.sampling_modulus - 1u)) + - 1u; + ctx.sampling.random_state = ((runtime_ev.request.sampling_seed - 1u) % + (ctx.policy.sampling_modulus - 1u)) + + 1u; } }; @@ -177,6 +176,7 @@ struct effect_begin_input_embedding { const auto &model = runtime_ev.request.model; const int32_t hidden_dim = ctx.session.hidden_dim; (void)model; + runtime_ev.ctx.err = detail_ns::to_error(error::none); runtime_ev.ctx.input_embedding_ok = false; runtime_ev.ctx.input_text_embedding_ok = false; runtime_ev.ctx.input_audio_embedding_ok = false; @@ -990,6 +990,7 @@ struct effect_restore_prediction_state_and_bind_text_logits { void operator()(const event::step_run &runtime_ev, context &ctx) const noexcept { const int32_t hidden_dim = ctx.session.hidden_dim; + runtime_ev.ctx.err = detail_ns::to_error(error::none); std::copy_n(runtime_ev.request.temporal_state.begin(), static_cast(hidden_dim), runtime_ev.ctx.normalized.data()); @@ -1107,7 +1108,6 @@ struct effect_reset_depformer_positions { emel::memory::streaming::event::reset{ .error_out = runtime_ev.ctx.depformer_position_error}); } - }; struct effect_advance_depformer_position { diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index a3bd2a0e..ac663099 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -1127,10 +1127,10 @@ struct sm : public emel::sm { bool process_event(const emel::speech::predictor::moshi::event::graph_step &ev) { - event::step_ctx ctx{}; - event::step_run runtime_ev{ev, ctx}; + event::step_run runtime_ev{ev, step_workspace_}; const bool accepted = base_type::process_event(runtime_ev); - return accepted && ctx.err == action::detail_ns::to_error(error::none); + return accepted && + step_workspace_.err == action::detail_ns::to_error(error::none); } bool process_event(const event::reset &ev) { @@ -1140,10 +1140,14 @@ struct sm : public emel::sm { return accepted && ctx.err == action::detail_ns::to_error(error::none); } - bool process_event( - const emel::speech::predictor::moshi::event::reset &) { + bool process_event(const emel::speech::predictor::moshi::event::reset &) { return process_event(event::reset{}); } + +private: + // Actor-owned numeric scratch is initialized once and reused synchronously. + // Entry actions reset scalar outcomes and only the active tensor extents. + event::step_ctx step_workspace_ = {}; }; } // namespace emel::speech::predictor::moshi::executor diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 369bcdf4..6e09b9a9 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -25,8 +25,11 @@ struct guard_bind_contract_valid { const bool personaplex = lm.depformer_weights_per_step; const int32_t delayed_dep_q = personaplex ? lm.inference_dep_q : lm.dep_q; const int32_t needed_tokens = codebook_count - delayed_dep_q - 1; - const int64_t row_count = static_cast(max_delay) + 2 + - static_cast(personaplex); + const int64_t row_count = + static_cast(max_delay) + 2 + static_cast(personaplex); + const int64_t reserved_token_capacity = + static_cast(runtime_ev.request.max_blocks) * + static_cast(runtime_ev.request.block_tokens); const bool inference_contract = !personaplex || (lm.inference_dep_q > 0 && lm.inference_dep_q <= lm.dep_q && @@ -43,7 +46,8 @@ struct guard_bind_contract_valid { lm.delay_count >= static_cast(codebook_count) && runtime_ev.request.max_sequences > 0 && runtime_ev.request.max_blocks > 0 && - runtime_ev.request.block_tokens > 0 && + runtime_ev.request.block_tokens > 0 && reserved_token_capacity > 0 && + reserved_token_capacity <= static_cast(lm.context) && runtime_ev.request.sequence_id >= 0 && runtime_ev.request.sequence_id < runtime_ev.request.max_sequences && runtime_ev.request.codebook_capacity >= codebook_count && @@ -106,7 +110,8 @@ struct guard_voice_contract_valid { embeddings->n_dims == 4 && embeddings->dims[0] == ctx.session.model->moshi_lm.dim && embeddings->dims[1] == 1 && embeddings->dims[2] == 1 && - embeddings->dims[3] > 0 && embeddings->dims[0] <= + embeddings->dims[3] > 0 && + embeddings->dims[0] <= static_cast(event::k_max_voice_embedding_dim) && embedding_type_ok && cache->n_dims == 2 && cache->dims[0] == ctx.lmgen.cache_row_count && diff --git a/src/emel/speech/tokenizer/moshi/guards.hpp b/src/emel/speech/tokenizer/moshi/guards.hpp index 36607651..e5b953f8 100644 --- a/src/emel/speech/tokenizer/moshi/guards.hpp +++ b/src/emel/speech/tokenizer/moshi/guards.hpp @@ -18,7 +18,7 @@ struct guard_configuration_valid { config.delayed_audio_codebooks <= 0 || config.delayed_audio_codebooks > config.generated_audio_codebooks || config.cache_rows <= 0 || config.maximum_delay < 0 || - config.initial_delay_frames < 0 || + config.initial_delay_frames < 0 || config.audio_initial_token <= 0 || config.token_zero == config.token_ungenerated || config.delays.size() < static_cast(config.codebooks)) { return false; @@ -99,12 +99,26 @@ struct guard_tokenize_empty_shape { } }; +struct guard_tokenize_tokens_valid { + bool operator()(const event::tokenize &ev, + const action::context &ctx) const noexcept { + bool valid = true; + for (const int32_t token : ev.audio_tokens) { + if (token < 0 || token >= ctx.config.audio_initial_token) { + valid = false; + } + } + return valid; + } +}; + struct guard_tokenize_shape_valid { bool operator()(const event::tokenize &ev, const action::context &ctx) const noexcept { - return guard_tokenize_full_shape{}(ev, ctx) || - guard_tokenize_tail_shape{}(ev, ctx) || - guard_tokenize_empty_shape{}(ev, ctx); + return (guard_tokenize_full_shape{}(ev, ctx) || + guard_tokenize_tail_shape{}(ev, ctx) || + guard_tokenize_empty_shape{}(ev, ctx)) && + guard_tokenize_tokens_valid{}(ev, ctx); } }; @@ -112,6 +126,7 @@ struct guard_tokenize_full { bool operator()(const event::tokenize &ev, const action::context &ctx) const noexcept { return guard_tokenize_full_shape{}(ev, ctx) && + guard_tokenize_tokens_valid{}(ev, ctx) && guard_tokenize_position_available{}(ev, ctx); } }; @@ -120,6 +135,7 @@ struct guard_tokenize_tail { bool operator()(const event::tokenize &ev, const action::context &ctx) const noexcept { return guard_tokenize_tail_shape{}(ev, ctx) && + guard_tokenize_tokens_valid{}(ev, ctx) && guard_tokenize_position_available{}(ev, ctx); } }; @@ -128,6 +144,7 @@ struct guard_tokenize_empty { bool operator()(const event::tokenize &ev, const action::context &ctx) const noexcept { return guard_tokenize_empty_shape{}(ev, ctx) && + guard_tokenize_tokens_valid{}(ev, ctx) && guard_tokenize_position_available{}(ev, ctx); } }; diff --git a/src/emel/speech/tokenizer/moshi/sm.hpp b/src/emel/speech/tokenizer/moshi/sm.hpp index 36d967ca..9a235770 100644 --- a/src/emel/speech/tokenizer/moshi/sm.hpp +++ b/src/emel/speech/tokenizer/moshi/sm.hpp @@ -15,6 +15,7 @@ namespace emel::speech::tokenizer::moshi { struct state_uninitialized {}; struct state_ready {}; struct state_prepared_full {}; +struct state_prepared_tail {}; struct state_prepared_generated {}; struct state_commit_full_zero {}; struct state_commit_full_generated {}; @@ -30,9 +31,10 @@ Moshi tokenizer architecture notes (single source of truth) state purpose - state_ready accepts the first half of a frame and tokenizes the caller's audio codebooks into the delay-aligned LM input sequence. -- state_prepared_full records that all codebooks were provided, while - state_prepared_generated records tail-only or generator-owned input. The - state graph therefore owns cache-write policy without a persistent flag. +- state_prepared_full records that all codebooks were provided, + state_prepared_tail records that PersonaPlex tail lanes were provided, and + state_prepared_generated records generator-owned input. The state graph + therefore owns cache-write policy without a persistent flag. - commit states select initial-delay replacement and provided-cache preservation before executing fixed data-plane cache writes. @@ -89,6 +91,9 @@ struct model { , sml::state <= sml::state + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} , sml::state <= sml::state + sml::event [ guard::guard_configuration_valid{} ] / action::effect_initialize{} @@ -102,7 +107,7 @@ struct model { , sml::state <= sml::state + sml::event [ guard::guard_tokenize_full{} ] / action::effect_tokenize_full{} - , sml::state <= sml::state + , sml::state <= sml::state + sml::event [ guard::guard_tokenize_tail{} ] / action::effect_tokenize_tail{} , sml::state <= sml::state @@ -121,6 +126,9 @@ struct model { , sml::state <= sml::state + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} //------------------------------------------------------------------------------// // Detokenization explicitly selects full-input preservation and initial @@ -133,6 +141,14 @@ struct model { + sml::event [ guard::guard_detokenize_valid_generated{} ] / action::effect_begin_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_valid_replace{} ] + / action::effect_begin_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_valid_generated{} ] + / action::effect_begin_detokenize{} , sml::state <= sml::state + sml::event [ guard::guard_detokenize_valid_replace{} ] @@ -149,12 +165,19 @@ struct model { + sml::event [ guard::guard_detokenize_shape_invalid{} ] / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event + [ guard::guard_detokenize_shape_invalid{} ] + / action::effect_reject_detokenize{} , sml::state <= sml::state + sml::event [ guard::guard_position_overflow{} ] / action::effect_reject_detokenize{} , sml::state <= sml::state + sml::event [ guard::guard_position_overflow{} ] / action::effect_reject_detokenize{} + , sml::state <= sml::state + + sml::event [ guard::guard_position_overflow{} ] + / action::effect_reject_detokenize{} , sml::state <= sml::state + sml::completion / effect_commit_full_zero{} , sml::state <= sml::state @@ -190,6 +213,9 @@ struct model { , sml::state <= sml::state + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event + / action::effect_reject{} , sml::state <= sml::state + sml::event [ guard::guard_advance_position_available{} ] / action::effect_advance{} @@ -199,6 +225,8 @@ struct model { / action::effect_reject{} , sml::state <= sml::state + sml::event / action::effect_reject{} + , sml::state <= sml::state + + sml::event / action::effect_reject{} , sml::state <= sml::state + sml::event / action::effect_reject{} , sml::state <= sml::state @@ -207,6 +235,8 @@ struct model { + sml::event / action::effect_reset{} , sml::state <= sml::state + sml::event / action::effect_reset{} + , sml::state <= sml::state + + sml::event / action::effect_reset{} , sml::state <= sml::state + sml::event / action::effect_reset{} @@ -248,6 +278,8 @@ struct model { + sml::unexpected_event / action::effect_unexpected{} , sml::state <= sml::state + sml::unexpected_event / action::effect_unexpected{} + , sml::state <= sml::state + + sml::unexpected_event / action::effect_unexpected{} , sml::state <= sml::state + sml::unexpected_event / action::effect_unexpected{} ); diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index 61960235..68a9e15e 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -29,6 +29,7 @@ struct fake_voice_condition { }; struct fake_prompt_begin { + int32_t text_token_count = 0; emel::error::type *error_out = nullptr; }; @@ -230,6 +231,7 @@ struct fake_predictor_actor { int32_t conditioning_initialize_calls = 0; int32_t voice_condition_calls = 0; int32_t prompt_begin_calls = 0; + int32_t prompt_begin_text_token_count = 0; int32_t prompt_condition_calls = 0; int32_t predict_calls = 0; int32_t execute_calls = 0; @@ -264,6 +266,7 @@ struct fake_predictor_actor { bool process_event(const fake_prompt_begin &request) noexcept { ++prompt_begin_calls; + prompt_begin_text_token_count = request.text_token_count; *request.error_out = prompt_begin_error; return prompt_begin_accepted; } @@ -349,6 +352,7 @@ struct fake_dependencies { fake_initialize decoder_initialize = {}; fake_initialize predictor_initialize = {}; fake_initialize conditioning_initialize = {}; + fake_prompt_begin prompt_begin{.text_token_count = 1}; std::span silence_pcm = {}; std::span input_codes = {}; std::span tokenize_input_codes = {}; @@ -668,6 +672,7 @@ TEST_CASE("speech_generator_conditions_without_model_family_contracts") { CHECK(test->machine.is(sml::state)); CHECK(test->predictor.voice_condition_calls == 1); CHECK(test->predictor.prompt_begin_calls == 1); + CHECK(test->predictor.prompt_begin_text_token_count == 1); REQUIRE(test->condition()); CHECK(test->machine.is(sml::state)); diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index de6c3fcc..4efcc0b8 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -83,8 +83,8 @@ void configure_predictor_initialize(moshi::event::initialize &request) { std::max(maximum_delay, request.model.moshi_lm.delays[index]); } request.max_sequences = 1; - request.max_blocks = 64; request.block_tokens = 4; + request.max_blocks = request.model.moshi_lm.context / request.block_tokens; request.sequence_id = 0; request.codebook_capacity = request.model.moshi_lm.n_q + 1; request.delay_cache_row_capacity = maximum_delay + 3; @@ -436,7 +436,7 @@ TEST_CASE("speech_moshi_generator_initializes_lm_with_injected_kv") { moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); init.max_sequences = 2; - init.max_blocks = 16; + init.max_blocks = fixture.model->moshi_lm.context / init.block_tokens; init.block_tokens = 4; init.error_out = &err; @@ -539,7 +539,7 @@ TEST_CASE( moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); - init.max_blocks = 32; + init.max_blocks = fixture.model->moshi_lm.context / init.block_tokens; init.block_tokens = 4; init.error_out = &err; REQUIRE(generator.process_event(init)); @@ -635,7 +635,7 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); - init.max_blocks = 48; + init.max_blocks = fixture.model->moshi_lm.context / init.block_tokens; init.block_tokens = 4; init.error_out = &err; REQUIRE(generator.process_event(init)); @@ -772,6 +772,30 @@ TEST_CASE("speech_moshi_generator_prefills_personaplex_system_prompt_before_" CHECK(graph.call_count == prompt_frames + 6); } +TEST_CASE("speech_moshi_predictor_rejects_memory_geometry_beyond_temporal_kv") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; + recording_graph_executor graph{}; + moshi::sm generator{make_predictor_dependencies(graph, memory)}; + emel::error::type err = k_no_error; + + moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); + init.max_blocks = fixture.model->moshi_lm.context; + init.block_tokens = 2; + init.error_out = &err; + + CHECK_FALSE(generator.process_event(init)); + CHECK(err == emel::error::cast(moshi::error::bind_failed)); + CHECK(kv.reserve_count == 0); + CHECK_FALSE(graph.initialized); +} + TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" "prompt") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); @@ -788,7 +812,7 @@ TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" moshi::event::initialize init{*fixture.model}; configure_predictor_initialize(init); - init.max_blocks = 48; + init.max_blocks = fixture.model->moshi_lm.context / init.block_tokens; init.block_tokens = 4; init.error_out = &err; REQUIRE(generator.process_event(init)); @@ -1043,26 +1067,25 @@ TEST_CASE("speech_moshi_executor_rejects_invalid_sampling_configuration") { return; } - const auto rejected = [&fixture](const float audio_temperature, - const float text_temperature, - const int32_t audio_top_k, - const int32_t text_top_k) { - emel::kernel::sm kernel{}; - emel::logits::sampler::sm sampler{}; - moshi_executor::sm executor{ - make_executor_dependencies(kernel, {}, &sampler)}; - emel::error::type err = emel::error::cast(moshi_executor::error::none); - moshi_executor::event::initialize init{*fixture.model}; - init.sampling_enabled = true; - init.sampling_audio_temperature = audio_temperature; - init.sampling_text_temperature = text_temperature; - init.sampling_audio_top_k = audio_top_k; - init.sampling_text_top_k = text_top_k; - init.sampling_seed = 1234u; - init.error_out = &err; - return !executor.process_event(init) && - err == emel::error::cast(moshi_executor::error::bind_failed); - }; + const auto rejected = + [&fixture](const float audio_temperature, const float text_temperature, + const int32_t audio_top_k, const int32_t text_top_k) { + emel::kernel::sm kernel{}; + emel::logits::sampler::sm sampler{}; + moshi_executor::sm executor{ + make_executor_dependencies(kernel, {}, &sampler)}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.sampling_enabled = true; + init.sampling_audio_temperature = audio_temperature; + init.sampling_text_temperature = text_temperature; + init.sampling_audio_top_k = audio_top_k; + init.sampling_text_top_k = text_top_k; + init.sampling_seed = 1234u; + init.error_out = &err; + return !executor.process_event(init) && + err == emel::error::cast(moshi_executor::error::bind_failed); + }; CHECK(rejected(std::numeric_limits::quiet_NaN(), 0.7f, 1, 1)); CHECK(rejected(0.8f, std::numeric_limits::quiet_NaN(), 1, 1)); @@ -1196,14 +1219,16 @@ TEST_CASE("speech_moshi_executor_runtime_choice_uses_explicit_transitions") { "moshi" / "executor" / "detail.hpp"); const std::string detail_source{detail_bytes.begin(), detail_bytes.end()}; const auto predictor_guard_bytes = - read_binary_file(repo_root() / "src" / "emel" / "speech" / - "predictor" / "moshi" / "guards.hpp"); + read_binary_file(repo_root() / "src" / "emel" / "speech" / "predictor" / + "moshi" / "guards.hpp"); const std::string predictor_guards_source{predictor_guard_bytes.begin(), predictor_guard_bytes.end()}; CHECK(source.find("infer_debug_phase") == std::string::npos); CHECK(source.find("debug_phase_out != nullptr") == std::string::npos); CHECK(source.find("effect_store_debug_phase_out") == std::string::npos); + CHECK(source.find("event::step_ctx ctx{}") == std::string::npos); + CHECK(source.find("step_workspace_") != std::string::npos); CHECK(source.find("if (ctx.depformer_logits_ok)") == std::string::npos); CHECK(actions_source.find("if (runtime_ev.ctx.temporal_out_norm_ok)") == std::string::npos); @@ -2276,8 +2301,7 @@ TEST_CASE( CHECK_FALSE(moshi_executor::detail::tensor_shape(&malformed_matrix, lm.dim, lm.dim * 3)); - std::array key_cache = - {}; + std::array key_cache = {}; std::array value_cache = {}; std::array offsets = {std::numeric_limits::max()}; @@ -2317,8 +2341,8 @@ TEST_CASE( CHECK_FALSE(moshi_executor::guard::guard_cache_span_valid( std::numeric_limits::max(), 1u, 1u, 1u, key_cache.size(), value_cache.size())); - CHECK(moshi_executor::guard::guard_sampling_step_invalid{}( - step_run, executor_ctx) != + CHECK(moshi_executor::guard::guard_sampling_step_invalid{}(step_run, + executor_ctx) != moshi_executor::guard::guard_sampling_step_valid{}(step_run, executor_ctx)); CHECK(moshi_executor::guard::guard_temporal_position_advance_failed{}( @@ -2349,11 +2373,10 @@ TEST_CASE( step_run, executor_ctx) != moshi_executor::guard::guard_temporal_layer_silu_gate_supported{}( step_run, executor_ctx)); - CHECK( - moshi_executor::guard::guard_temporal_layer_silu_gate_silu_failed{}( - step_run, executor_ctx) != - moshi_executor::guard::guard_temporal_layer_silu_gate_silu_succeeded{}( - step_run, executor_ctx)); + CHECK(moshi_executor::guard::guard_temporal_layer_silu_gate_silu_failed{}( + step_run, executor_ctx) != + moshi_executor::guard::guard_temporal_layer_silu_gate_silu_succeeded{}( + step_run, executor_ctx)); CHECK(moshi_executor::guard::guard_temporal_layer_silu_gate_failed{}( step_run, executor_ctx) != moshi_executor::guard::guard_temporal_layer_silu_gate_succeeded{}( @@ -2382,12 +2405,12 @@ TEST_CASE( step_run, executor_ctx) != moshi_executor::guard::guard_temporal_out_norm_rms_succeeded{}( step_run, executor_ctx)); - CHECK(moshi_executor::guard::guard_temporal_out_norm_failed{}( - step_run, executor_ctx) != + CHECK(moshi_executor::guard::guard_temporal_out_norm_failed{}(step_run, + executor_ctx) != moshi_executor::guard::guard_temporal_out_norm_succeeded{}( step_run, executor_ctx)); - CHECK(moshi_executor::guard::guard_text_logits_unsupported{}( - step_run, executor_ctx) != + CHECK(moshi_executor::guard::guard_text_logits_unsupported{}(step_run, + executor_ctx) != moshi_executor::guard::guard_text_logits_supported{}(step_run, executor_ctx)); CHECK(moshi_executor::guard::guard_text_logits_matmul_failed{}( @@ -2398,8 +2421,8 @@ TEST_CASE( executor_ctx) != moshi_executor::guard::guard_text_logits_succeeded{}(step_run, executor_ctx)); - CHECK(moshi_executor::guard::guard_text_sampling_failed{}( - step_run, executor_ctx) != + CHECK(moshi_executor::guard::guard_text_sampling_failed{}(step_run, + executor_ctx) != moshi_executor::guard::guard_text_sampling_succeeded{}(step_run, executor_ctx)); } diff --git a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp index b6407bae..f836fe13 100644 --- a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp +++ b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp @@ -146,7 +146,7 @@ TEST_CASE("speech Moshi tokenizer accepts the PersonaPlex tail shape") { int32_t err = error_code(moshi::error::none); REQUIRE(machine.process_event(moshi::event::initialize{.error_out = err})); - std::array tail = {301, 302}; + std::array tail = {101, 102}; std::array model_tokens = {}; REQUIRE(machine.process_event(moshi::event::tokenize{ .audio_tokens = std::span{tail}, @@ -168,6 +168,43 @@ TEST_CASE("speech Moshi tokenizer accepts the PersonaPlex tail shape") { .error_out = err, })); CHECK_FALSE(produced); + + const std::array next_tail = {111, 112}; + REQUIRE(machine.process_event(moshi::event::tokenize{ + .audio_tokens = std::span{next_tail}, + .model_tokens_out = std::span{model_tokens}, + .error_out = err, + })); + REQUIRE(machine.process_event(moshi::event::detokenize{ + .text_token = 20, + .audio_tokens = std::span{generated}, + .text_token_out = text_out, + .audio_tokens_out = std::span{output}, + .produced_out = produced, + .error_out = err, + })); + const std::array third_tail = {121, 122}; + REQUIRE(machine.process_event(moshi::event::tokenize{ + .audio_tokens = std::span{third_tail}, + .model_tokens_out = std::span{model_tokens}, + .error_out = err, + })); + CHECK(model_tokens[3] == next_tail[0]); + CHECK(model_tokens[4] == next_tail[1]); +} + +TEST_CASE("speech Moshi tokenizer rejects invalid public audio tokens before " + "caching") { + standard_fixture state; + REQUIRE(state.initialize()); + + const std::array invalid_input = {50, 200, 52}; + CHECK(state.tokenize(invalid_input)); + CHECK(state.err == error_code(moshi::error::request_shape)); + CHECK(state.machine.is(sml::state)); + + REQUIRE(state.tokenize()); + CHECK(state.model_tokens == std::array{100, 200, 200}); } TEST_CASE("speech Moshi tokenizer masks initial delayed audio explicitly") { @@ -209,7 +246,8 @@ TEST_CASE("speech Moshi tokenizer restores column-major voice cache") { CHECK(state.model_tokens == std::array{12, 22, 200}); } -TEST_CASE("speech Moshi tokenizer does not publish restored ungenerated output") { +TEST_CASE( + "speech Moshi tokenizer does not publish restored ungenerated output") { standard_fixture state; REQUIRE(state.initialize()); diff --git a/tools/bench/speech/personaplex_emel_runner.cpp b/tools/bench/speech/personaplex_emel_runner.cpp index a115b75b..40979580 100644 --- a/tools/bench/speech/personaplex_emel_runner.cpp +++ b/tools/bench/speech/personaplex_emel_runner.cpp @@ -109,6 +109,7 @@ struct personaplex_dependencies { mimi::event::initialize decoder_initialize; predictor::event::initialize predictor_initialize; predictor::event::load_voice conditioning_initialize; + predictor::event::begin_personaplex_prompt prompt_begin = {}; std::span silence_pcm = {}; std::span input_codes = {}; std::span tokenize_input_codes = {}; @@ -636,6 +637,14 @@ int main(int argc, char **argv) { .predictor_initialize = predictor_initialize, .conditioning_initialize = predictor::event::load_voice{*voice_model.model}, + .prompt_begin = + predictor::event::begin_personaplex_prompt{ + .text_token_count = config.prompt_text_token >= 0 ? 1 : 0, + .pre_text_silence_frames = + lm_model.model->moshi_lm.inference_pre_text_silence_frames, + .post_text_silence_frames = + lm_model.model->moshi_lm.inference_post_text_silence_frames, + }, .silence_pcm = std::span{pcm_frame}, .input_codes = std::span{input_codes}, .tokenize_input_codes = std::span{input_codes}, From 517ea1f4164a8c6a1369bfb58493cc35274d228c Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 11:11:44 -0500 Subject: [PATCH 55/61] fix scheduled depformer init validation --- snapshots/lint/clang_format.txt | 1 - .../predictor/moshi/executor/guards.hpp | 51 ++++++++++++------- .../predictor/moshi_lifecycle_tests.cpp | 33 ++++++++++++ 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index cfe18b94..31c1b1c3 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -363,7 +363,6 @@ src/emel/speech/encoder/whisper/context.hpp src/emel/speech/encoder/whisper/errors.hpp src/emel/speech/encoder/whisper/guards.hpp src/emel/speech/predictor/moshi/events.hpp -src/emel/speech/predictor/moshi/executor/guards.hpp src/emel/tensor/view/actions.hpp src/emel/tensor/view/context.hpp src/emel/tensor/view/detail.hpp diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 078097e8..64abd664 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -17,15 +17,13 @@ inline bool guard_cache_span_valid(const size_t layer_offset, const size_t dim, const size_t key_cache_size, const size_t value_cache_size) noexcept { - if (dim == 0u || first_position > - std::numeric_limits::max() / dim || + if (dim == 0u || first_position > std::numeric_limits::max() / dim || position_count > std::numeric_limits::max() / dim) { return false; } const size_t first_element = first_position * dim; const size_t element_count = position_count * dim; - if (layer_offset > - std::numeric_limits::max() - first_element) { + if (layer_offset > std::numeric_limits::max() - first_element) { return false; } const size_t begin = layer_offset + first_element; @@ -54,12 +52,10 @@ struct guard_bind_contract_valid { model.moshi_lm.text_card > 0 && model.moshi_lm.card > 0 && model.moshi_lm.dim > 0 && (!runtime_ev.request.sampling_enabled || ctx.sampler != nullptr) && - sampling_config_valid && - ctx.policy.rms_norm_epsilon > 0.0f && + sampling_config_valid && ctx.policy.rms_norm_epsilon > 0.0f && ctx.policy.sampling_modulus > 1u && ctx.policy.zero_seed_state % ctx.policy.sampling_modulus != 0u && - ctx.policy.token_zero < 0 && - ctx.capacity.hidden_dim > 0u && + ctx.policy.token_zero < 0 && ctx.capacity.hidden_dim > 0u && ctx.capacity.hidden_dim <= detail::k_max_hidden_dim && ctx.capacity.temporal_context > 0u && ctx.capacity.temporal_context <= detail::k_max_temporal_context && @@ -116,18 +112,35 @@ struct guard_bound_root_operands_supported { detail::supported_get_rows_dtype( static_cast(depformer_text_embedding->type)); for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { - const auto *input_projection = - ctx.session.contract.lm - .depformer_input_projections[static_cast(codebook)] - .tensor; + int32_t weight_index = codebook; + if (lm.depformer_weight_schedule_count > 0u) { + if (static_cast(codebook) >= + lm.depformer_weight_schedule_count) { + supported = false; + } else { + weight_index = + lm.depformer_weight_schedule[static_cast(codebook)]; + } + } + if (weight_index < 0 || weight_index >= lm.dep_q) { + supported = false; + } else { + const auto *input_projection = + ctx.session.contract.lm + .depformer_input_projections[static_cast(weight_index)] + .tensor; + supported = + supported && + detail::tensor_shape(input_projection, hidden_dim, dep_dim) && + detail::supported_mul_mat_dtype( + static_cast(input_projection->type)); + } + const auto *output_projection = ctx.session.contract.lm .depformer_output_projections[static_cast(codebook)] .tensor; supported = supported && - detail::tensor_shape(input_projection, hidden_dim, dep_dim) && - detail::supported_mul_mat_dtype( - static_cast(input_projection->type)) && detail::tensor_shape(output_projection, dep_dim, lm.card) && detail::supported_argmax_dtype( static_cast(output_projection->type)); @@ -2233,8 +2246,8 @@ struct guard_reset_temporal_positions_succeeded { const action::context &) const noexcept { return runtime_ev.ctx.temporal_position_accepted && runtime_ev.ctx.temporal_position_error == - static_cast(emel::error::cast( - emel::memory::streaming::error::none)); + static_cast( + emel::error::cast(emel::memory::streaming::error::none)); } }; @@ -2264,8 +2277,8 @@ struct guard_reset_depformer_positions_succeeded { const action::context &) const noexcept { return runtime_ev.ctx.depformer_position_accepted && runtime_ev.ctx.depformer_position_error == - static_cast(emel::error::cast( - emel::memory::streaming::error::none)); + static_cast( + emel::error::cast(emel::memory::streaming::error::none)); } }; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 4efcc0b8..5e486271 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -796,6 +796,39 @@ TEST_CASE("speech_moshi_predictor_rejects_memory_geometry_beyond_temporal_kv") { CHECK_FALSE(graph.initialized); } +TEST_CASE( + "speech_moshi_executor_init_honors_shared_depformer_weight_schedule") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + auto &lm = fixture.model->moshi_lm; + REQUIRE(lm.dep_q >= 2); + + emel::kernel::sm kernel{}; + moshi_executor::action::context ctx{make_executor_dependencies(kernel)}; + moshi_executor::event::initialize request{*fixture.model}; + moshi_executor::event::initialize_ctx request_ctx{}; + moshi_executor::event::initialize_run runtime_ev{request, request_ctx}; + moshi_executor::action::effect_bind_contract{}(runtime_ev, ctx); + REQUIRE(moshi_executor::guard::guard_bound_root_operands_supported{}( + runtime_ev, ctx)); + + lm.depformer_weight_schedule_count = static_cast(lm.dep_q); + for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + lm.depformer_weight_schedule[static_cast(codebook)] = codebook; + } + lm.depformer_weight_schedule[static_cast(lm.dep_q - 1)] = + lm.dep_q - 2; + ctx.session.contract.lm + .depformer_input_projections[static_cast(lm.dep_q - 1)] + .tensor = nullptr; + + CHECK(moshi_executor::guard::guard_bound_root_operands_supported{}(runtime_ev, + ctx)); +} + TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" "prompt") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); From e4930504c728b0a8f614e5e47f70f8afd985c79a Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 11:33:24 -0500 Subject: [PATCH 56/61] fix PersonaPlex comparison contracts --- docs/benchmarking.md | 9 ++--- snapshots/lint/clang_format.txt | 2 -- src/emel/model/moshi/detail.cpp | 44 ++++++++++++----------- tests/model/moshi/binding_tests.cpp | 14 ++++++-- tools/bench/personaplex_compare.py | 10 ++++++ tools/bench/personaplex_compare_tests.cpp | 8 ++++- 6 files changed, 57 insertions(+), 30 deletions(-) diff --git a/docs/benchmarking.md b/docs/benchmarking.md index 8494a2fe..d6f58261 100644 --- a/docs/benchmarking.md +++ b/docs/benchmarking.md @@ -415,10 +415,11 @@ full 16-codebook Mimi parity artifact separate from PersonaPlex's 8-public-codeb the report and both audible WAVs are written under `build/personaplex_compare/`. the report records the input SHA256, EMEL/reference LM and Mimi paths and SHA256 values, exact public Mimi input-code -match, sampled output-token match, text-token match, lagged 80 ms energy correlation, activity -ratio, non-silence, output hashes, and end-to-end wall time. sampled output is compared as behavior -rather than raw-waveform equality because a one-rank floating-point difference can avalanche later -fixed-seed draws even when the RNG state and sampling policy agree. +match, sampled output-token match, exact text frame/token match, lagged 80 ms energy correlation, +activity ratio, non-silence, output hashes, and end-to-end wall time. A text frame-count or token +drift fails the comparison. sampled audio output is compared as behavior rather than raw-waveform +equality because a one-rank floating-point difference can avalanche later fixed-seed draws even +when the RNG state and sampling policy agree. use `--emel-lm` and `--emel-mimi` (or `EMEL_PERSONAPLEX_EMEL_LM` and `EMEL_PERSONAPLEX_EMEL_MIMI`) to inject packed or quantized EMEL artifacts without changing the diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index 31c1b1c3..6df20403 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -337,7 +337,6 @@ src/emel/model/loader/context.hpp src/emel/model/loader/detail.hpp src/emel/model/loader/events.hpp src/emel/model/loader/guards.hpp -src/emel/model/moshi/detail.cpp src/emel/model/omniembed/detail.cpp src/emel/model/omniembed/detail.hpp src/emel/model/qwen3/detail.cpp @@ -593,7 +592,6 @@ tests/memory/kv/lifecycle_tests.cpp tests/memory/recurrent/lifecycle_tests.cpp tests/model/fixture_manifest_tests.cpp tests/model/loader/lifecycle_tests.cpp -tests/model/moshi/binding_tests.cpp tests/model/tensor/lifecycle_tests.cpp tests/model/tensor/window/lifecycle_tests.cpp tests/model/tensor/window/streaming_tests.cpp diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index 321737cb..b2a0407c 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -154,9 +154,10 @@ bool require_i32_array(const emel::model::detail::kv_binding &binding, return true; } -bool assign_optional_i32_array( - const emel::model::detail::kv_binding &binding, const std::string_view key, - const std::span dst, uint32_t &count_out) noexcept { +bool assign_optional_i32_array(const emel::model::detail::kv_binding &binding, + const std::string_view key, + const std::span dst, + uint32_t &count_out) noexcept { const auto *entry = emel::model::detail::find_kv_entry(binding, key); if (entry == nullptr) { count_out = 0u; @@ -816,26 +817,27 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, *depformer_text_embedding), }; for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { - if (!required_weight_indices[static_cast(codebook)]) { - continue; - } char name[96] = {}; - int written = std::snprintf(name, sizeof(name), - "lm.depformer_in.%d.weight", codebook); - if (written <= 0 || static_cast(written) >= sizeof(name)) { - return emel::error::cast(emel::model::loader::error::model_invalid); - } - const auto *input_projection = find_tensor( - model_data, std::string_view{name, static_cast(written)}); - if (input_projection == nullptr) { - return emel::error::cast(emel::model::loader::error::model_invalid); + int written = 0; + if (required_weight_indices[static_cast(codebook)]) { + written = std::snprintf(name, sizeof(name), "lm.depformer_in.%d.weight", + codebook); + if (written <= 0 || static_cast(written) >= sizeof(name)) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + const auto *input_projection = find_tensor( + model_data, std::string_view{name, static_cast(written)}); + if (input_projection == nullptr) { + return emel::error::cast(emel::model::loader::error::model_invalid); + } + contract_out + .depformer_input_projections[static_cast(codebook)] = + tensor_view{ + .tensor = input_projection, + .name = emel::model::tensor_name_view(model_data, + *input_projection), + }; } - contract_out.depformer_input_projections[static_cast(codebook)] = - tensor_view{ - .tensor = input_projection, - .name = - emel::model::tensor_name_view(model_data, *input_projection), - }; written = std::snprintf(name, sizeof(name), "lm.linears.%d.weight", codebook); diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index 940d1796..fd047f79 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -590,8 +590,8 @@ TEST_CASE("moshi lm contract binds only scheduled depformer weight sets") { for (uint32_t index = 0; index < model->n_tensors; ++index) { auto &tensor = model->tensors[index]; - const std::string_view name{ - model->name_storage.data() + tensor.name_offset, tensor.name_length}; + const std::string_view name{model->name_storage.data() + tensor.name_offset, + tensor.name_length}; const std::size_t codebook = name.find(".3."); if ((name.starts_with("lm.depformer_in.") || name.starts_with("lm.depformer.layers.")) && @@ -641,6 +641,16 @@ TEST_CASE("moshi lm contract rejects invalid scheduled tensor bindings") { constexpr std::string_view name = "lm.linears.1.weight"; REQUIRE(hide_tensor(name, name.find(".1.") + 1u)); } + SUBCASE("unscheduled codebook output projection is still required") { + model->moshi_lm.depformer_weights_per_step = true; + model->moshi_lm.depformer_weight_schedule_count = 4u; + model->moshi_lm.depformer_weight_schedule[0] = 0; + model->moshi_lm.depformer_weight_schedule[1] = 1; + model->moshi_lm.depformer_weight_schedule[2] = 1; + model->moshi_lm.depformer_weight_schedule[3] = 2; + constexpr std::string_view name = "lm.linears.3.weight"; + REQUIRE(hide_tensor(name, name.find(".3.") + 1u)); + } CHECK(moshi::validate_execution_contract(*model) != k_none); } diff --git a/tools/bench/personaplex_compare.py b/tools/bench/personaplex_compare.py index 3118a1f6..842c917e 100755 --- a/tools/bench/personaplex_compare.py +++ b/tools/bench/personaplex_compare.py @@ -90,6 +90,15 @@ def common_token_prefix(left: list[list[int]], right: list[list[int]]) -> int: return count +def append_text_parity_reason(reasons: list[str], emel_text: list[int], + ref_text: list[int], text_match: float) -> None: + if len(emel_text) != len(ref_text): + reasons.append("text frame count mismatch") + elif text_match != 1.0: + reasons.append( + f"text token match is {text_match:.6f}, expected 1.0") + + def read_wav(path: Path) -> tuple[int, list[float]]: with wave.open(str(path), "rb") as source: if (source.getnchannels(), source.getsampwidth()) != (1, 2): @@ -286,6 +295,7 @@ def main() -> int: reasons.append("input frame count mismatch") if len(emel_output) != args.frames or len(ref_output) != args.frames: reasons.append("output frame count mismatch") + append_text_parity_reason(reasons, emel_text, ref_text, text_match) if input_match != 1.0: reasons.append(f"same-WAV input token match is {input_match:.6f}, expected 1.0") if output_match < args.min_output_match: diff --git a/tools/bench/personaplex_compare_tests.cpp b/tools/bench/personaplex_compare_tests.cpp index c1164c40..1d57a522 100644 --- a/tools/bench/personaplex_compare_tests.cpp +++ b/tools/bench/personaplex_compare_tests.cpp @@ -76,7 +76,13 @@ TEST_CASE("personaplex compare math reports exact and partial token behavior") { "assert m.match_fraction([[1,9]], [[1,2]], 2) == 0.5; " "assert m.match_fraction([[1]], [[1,2]], 2) == 0.0; " "assert m.common_token_prefix([[1,2]], [[1,3]]) == 1; " - "assert abs(m.correlation([1.0,2.0,3.0], [2.0,4.0,6.0])-1.0) < 1e-12"; + "assert abs(m.correlation([1.0,2.0,3.0], [2.0,4.0,6.0])-1.0) < 1e-12; " + "reasons=[]; m.append_text_parity_reason(reasons, [1,2], [1,3], 0.5); " + "assert reasons == ['text token match is 0.500000, expected 1.0']; " + "reasons=[]; m.append_text_parity_reason(reasons, [1], [1,2], 0.0); " + "assert reasons == ['text frame count mismatch']; " + "reasons=[]; m.append_text_parity_reason(reasons, [1,2], [1,2], 1.0); " + "assert reasons == []"; CHECK(command_exit_code("python3 -c " + quote_arg_posix(program)) == 0); } From fa4eae8d535343c6fc0dc1b050712563c7ca62d2 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 12:24:38 -0500 Subject: [PATCH 57/61] fix remaining speech lifecycle review findings --- src/emel/speech/generator/actions.hpp | 55 ++++++++++- .../predictor/moshi/executor/guards.hpp | 48 +++++++++- src/emel/speech/predictor/moshi/sm.hpp | 6 ++ tests/speech/generator/lifecycle_tests.cpp | 91 +++++++++++++++++++ .../predictor/moshi_lifecycle_tests.cpp | 48 ++++++++++ 5 files changed, 243 insertions(+), 5 deletions(-) diff --git a/src/emel/speech/generator/actions.hpp b/src/emel/speech/generator/actions.hpp index c4d91620..3bf12f21 100644 --- a/src/emel/speech/generator/actions.hpp +++ b/src/emel/speech/generator/actions.hpp @@ -3,6 +3,8 @@ #include #include +#include + #include "emel/batch/planner/events.hpp" #include "emel/error/error.hpp" #include "emel/memory/streaming/errors.hpp" @@ -712,9 +714,58 @@ struct effect_reject_reset { }; template struct effect_unexpected { + static void + effect_reject_origin(const event::initialize_run &runtime_ev, + const context &ctx) noexcept { + effect_fail_initialize{}( + runtime_ev, ctx); + } + + static void + effect_reject_origin(const event::condition_run &runtime_ev, + const context &ctx) noexcept { + effect_fail_condition{}( + runtime_ev, ctx); + } + + static void + effect_reject_origin(const event::generate_run &runtime_ev, + const context &ctx) noexcept { + effect_fail_generate{}(runtime_ev, + ctx); + } + + static void + effect_reject_origin(const event::stream_frame_run &runtime_ev, + const context &ctx) noexcept { + effect_fail_stream_frame{}( + runtime_ev, ctx); + } + + static void + effect_reject_origin(const event::flush_run &runtime_ev, + const context &ctx) noexcept { + effect_fail_flush{}(runtime_ev, + ctx); + } + + static void + effect_reject_origin(const event::reset &ev, + const context &ctx) noexcept { + effect_reject_reset{}(ev, ctx); + } + template - void operator()(const event_type &, - const context &) const noexcept {} + static void + effect_reject_origin(const event_type &, + const context &) noexcept {} + + template + void operator()(const unexpected_type &unexpected, + const context &ctx) const noexcept { + effect_reject_origin(stateforward::sml::back::get_origin_event(unexpected), + ctx); + } }; } // namespace emel::speech::generator::action diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index 64abd664..ed94b9cb 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -204,8 +204,22 @@ struct guard_bound_root_operands_supported { detail::tensor_shape(norm2, dep_dim) && static_cast(norm2->type) == detail::dtype::f32; for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + int32_t weight_index = codebook; + if (lm.depformer_weight_schedule_count > 0u) { + if (static_cast(codebook) >= + lm.depformer_weight_schedule_count) { + supported = false; + } else { + weight_index = + lm.depformer_weight_schedule[static_cast(codebook)]; + } + } + if (weight_index < 0 || weight_index >= lm.dep_q) { + supported = false; + continue; + } const auto &codebook_layer = - layer.codebooks[static_cast(codebook)]; + layer.codebooks[static_cast(weight_index)]; const auto *output_projection = codebook_layer.output_projection.tensor; const auto *gating_input = codebook_layer.gating_input.tensor; const auto *gating_output = codebook_layer.gating_output.tensor; @@ -302,10 +316,24 @@ struct guard_depformer_split_projection_layout_supported { for (int32_t layer_index = 0; layer_index < lm.depformer_num_layers; ++layer_index) { for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + int32_t weight_index = codebook; + if (lm.depformer_weight_schedule_count > 0u) { + if (static_cast(codebook) >= + lm.depformer_weight_schedule_count) { + supported = false; + } else { + weight_index = + lm.depformer_weight_schedule[static_cast(codebook)]; + } + } + if (weight_index < 0 || weight_index >= lm.dep_q) { + supported = false; + continue; + } const auto *projection = ctx.session.contract.lm .depformer_layers[static_cast(layer_index)] - .codebooks[static_cast(codebook)] + .codebooks[static_cast(weight_index)] .split_input_projection.tensor; supported = supported && detail::tensor_shape(projection, lm.depformer_dim, @@ -329,10 +357,24 @@ struct guard_depformer_fused_projection_layout_supported { for (int32_t layer_index = 0; layer_index < lm.depformer_num_layers; ++layer_index) { for (int32_t codebook = 0; codebook < lm.dep_q; ++codebook) { + int32_t weight_index = codebook; + if (lm.depformer_weight_schedule_count > 0u) { + if (static_cast(codebook) >= + lm.depformer_weight_schedule_count) { + supported = false; + } else { + weight_index = + lm.depformer_weight_schedule[static_cast(codebook)]; + } + } + if (weight_index < 0 || weight_index >= lm.dep_q) { + supported = false; + continue; + } const auto *projection = ctx.session.contract.lm .depformer_layers[static_cast(layer_index)] - .codebooks[static_cast(codebook)] + .codebooks[static_cast(weight_index)] .fused_input_projection.tensor; supported = supported && detail::tensor_shape(projection, lm.depformer_dim, diff --git a/src/emel/speech/predictor/moshi/sm.hpp b/src/emel/speech/predictor/moshi/sm.hpp index 51353609..c19256b6 100644 --- a/src/emel/speech/predictor/moshi/sm.hpp +++ b/src/emel/speech/predictor/moshi/sm.hpp @@ -607,6 +607,12 @@ template struct model { + sml::event [ guard::guard_capture_tokenizer_state_invalid{} ] / action::effect_reject_capture_tokenizer_state{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_capture_tokenizer_state{} + , sml::state <= sml::state + + sml::event + / action::effect_reject_capture_tokenizer_state{} //------------------------------------------------------------------------------// // Requests before initialization answer with explicit errors. diff --git a/tests/speech/generator/lifecycle_tests.cpp b/tests/speech/generator/lifecycle_tests.cpp index 68a9e15e..a4838580 100644 --- a/tests/speech/generator/lifecycle_tests.cpp +++ b/tests/speech/generator/lifecycle_tests.cpp @@ -795,6 +795,97 @@ TEST_CASE("speech_generator_streams_through_injected_actor_pipeline") { CHECK(pcm_out[0] == doctest::Approx(0.25f)); } +TEST_CASE("speech_generator_rejects_stream_before_initialization") { + auto test = std::make_unique(); + std::array pcm_in{}; + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = 77; + int32_t sample_count = 77; + bool produced = true; + emel::error::type err = generator::action::error_code(generator::error::none); + generator::event::stream_frame request{std::span{pcm_in}, + std::span{pcm_out}, + std::span{encoded}, + std::span{generated}, + text_token, + sample_count, + produced, + err}; + CHECK_FALSE(test->machine.process_event(request)); + CHECK(err == generator::action::error_code(generator::error::internal_error)); + CHECK(sample_count == 0); + CHECK_FALSE(produced); +} + +TEST_CASE("speech_generator_rejects_other_public_requests_outside_lifecycle") { + const auto internal_error = + generator::action::error_code(generator::error::internal_error); + + SUBCASE("second initialization") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + emel::error::type err = + generator::action::error_code(generator::error::none); + CHECK_FALSE(test->machine.process_event(generator::event::initialize{err})); + CHECK(err == internal_error); + } + + SUBCASE("conditioning before initialization") { + auto test = std::make_unique(); + bool complete = true; + int32_t remaining = 77; + emel::error::type err = + generator::action::error_code(generator::error::none); + CHECK_FALSE(test->machine.process_event( + generator::event::condition{7, complete, remaining, err})); + CHECK(err == internal_error); + CHECK_FALSE(complete); + CHECK(remaining == -1); + } + + SUBCASE("generation before initialization") { + auto test = std::make_unique(); + std::array pcm_out{}; + int32_t sample_count = 77; + emel::error::type err = + generator::action::error_code(generator::error::none); + CHECK_FALSE(test->machine.process_event(generator::event::generate{ + "hello", std::span{pcm_out}, sample_count, err})); + CHECK(err == internal_error); + CHECK(sample_count == 0); + } + + SUBCASE("flush before initialization") { + auto test = std::make_unique(); + std::array pcm_out{}; + std::array encoded{}; + std::array generated{}; + int32_t text_token = 77; + int32_t sample_count = 77; + bool complete = true; + emel::error::type err = + generator::action::error_code(generator::error::none); + CHECK_FALSE(test->machine.process_event(generator::event::flush{ + std::span{pcm_out}, std::span{encoded}, + std::span{generated}, text_token, sample_count, complete, + err})); + CHECK(err == internal_error); + CHECK(sample_count == 0); + CHECK_FALSE(complete); + } + + SUBCASE("reset while conditioning") { + auto test = std::make_unique(); + REQUIRE(test->initialize()); + emel::error::type err = + generator::action::error_code(generator::error::none); + CHECK_FALSE(test->machine.process_event(generator::event::reset{err})); + CHECK(err == internal_error); + } +} + TEST_CASE("speech_generator_reports_frame_planning_failure") { auto test = std::make_unique( 4, 2, static_cast(99)); diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 5e486271..3649a3e5 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -827,6 +827,54 @@ TEST_CASE( CHECK(moshi_executor::guard::guard_bound_root_operands_supported{}(runtime_ev, ctx)); + for (int32_t layer = 0; layer < lm.depformer_num_layers; ++layer) { + auto &unused = + ctx.session.contract.lm.depformer_layers[static_cast(layer)] + .codebooks[static_cast(lm.dep_q - 1)]; + unused.output_projection.tensor = nullptr; + unused.gating_input.tensor = nullptr; + unused.gating_output.tensor = nullptr; + unused.split_input_projection.tensor = nullptr; + unused.fused_input_projection.tensor = nullptr; + } + CHECK(moshi_executor::guard::guard_bound_root_operands_supported{}(runtime_ev, + ctx)); + CHECK_FALSE( + moshi_executor::guard::guard_depformer_projection_layout_unsupported{}( + runtime_ev, ctx)); +} + +TEST_CASE("speech_moshi_predictor_rejects_tokenizer_capture_outside_ready") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + emel::memory::test::recording_kv_actor kv{}; + emel::memory::hybrid::sm memory{emel::memory::hybrid::bind_kv_actor(kv)}; + recording_graph_executor graph{}; + moshi::sm predictor{make_predictor_dependencies(graph, memory)}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); + init.error_out = &err; + REQUIRE(predictor.process_event(init)); + std::array tokens{}; + moshi::event::predict::workspace workspace{}; + moshi::event::predict predict{ + std::span{ + tokens.data(), static_cast(fixture.model->moshi_lm.n_q + 1)}, + workspace, 1, 1}; + predict.error_out = &err; + REQUIRE(predictor.process_event(predict)); + std::array + cache{}; + int64_t offset = -1; + err = k_no_error; + CHECK_FALSE(predictor.process_event(moshi::event::capture_tokenizer_state{ + std::span{cache}, offset, err})); + CHECK(err == emel::error::cast(moshi::error::request_shape)); + CHECK(offset == 0); } TEST_CASE("speech_moshi_generator_accepts_personaplex_voice_without_system_" From de227fff9648295bdd93f7e7f057b5852fdc00c0 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 13:01:13 -0500 Subject: [PATCH 58/61] fix speech token and capacity validation --- src/emel/model/moshi/detail.cpp | 30 +++++++++++++--- .../predictor/moshi/executor/guards.hpp | 28 +++++++++++++-- .../speech/predictor/moshi/executor/sm.hpp | 3 ++ src/emel/speech/tokenizer/moshi/guards.hpp | 32 ++++++++++++++--- src/emel/speech/tokenizer/moshi/sm.hpp | 6 ++-- tests/model/moshi/binding_tests.cpp | 21 +++++++++++- .../predictor/moshi_lifecycle_tests.cpp | 34 +++++++++++++++++++ .../tokenizer/moshi/lifecycle_tests.cpp | 25 +++++++++++--- 8 files changed, 159 insertions(+), 20 deletions(-) diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index b2a0407c..545ec429 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -560,6 +560,26 @@ bool require_tensor_shape(const emel::model::data &model_data, return true; } +bool require_lm_embedding_tensor_shape( + const emel::model::data &model_data, const std::string_view name, + const std::initializer_list dims) noexcept { + if (!require_tensor_shape(model_data, name, dims)) { + return false; + } + const auto *tensor = find_tensor(model_data, name); + switch (tensor->type) { + case 0: // F32 + case 1: // F16 + case 2: // Q4_0 + case 8: // Q8_0 + case 12: // Q4_K + case 30: // BF16 + return true; + default: + return false; + } +} + bool has_indexed_tensor(const emel::model::data &model_data, const char *format, const int32_t index) noexcept { char buffer[96] = {}; @@ -654,7 +674,8 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, {dim, text_card + 1}) && require_tensor_shape(model_data, "lm.text_linear.weight", {dim, text_card}) && - require_tensor_shape(model_data, "lm.emb.0.weight", {dim, card + 1}) && + require_lm_embedding_tensor_shape(model_data, "lm.emb.0.weight", + {dim, card + 1}) && has_tensor(model_data, "lm.out_norm.alpha"); if (!shapes_ok) { return emel::error::cast(emel::model::loader::error::model_invalid); @@ -687,11 +708,12 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, if (written <= 0 || static_cast(written) >= sizeof(name)) { return emel::error::cast(emel::model::loader::error::model_invalid); } - const auto *audio_embedding = find_tensor( - model_data, std::string_view{name, static_cast(written)}); - if (audio_embedding == nullptr) { + const std::string_view embedding_name{name, static_cast(written)}; + if (!require_lm_embedding_tensor_shape(model_data, embedding_name, + {dim, card + 1})) { return emel::error::cast(emel::model::loader::error::model_invalid); } + const auto *audio_embedding = find_tensor(model_data, embedding_name); contract_out.audio_embeddings[static_cast(codebook)] = tensor_view{ .tensor = audio_embedding, .name = emel::model::tensor_name_view(model_data, *audio_embedding), diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index ed94b9cb..abbd0b91 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -64,7 +65,20 @@ struct guard_bind_contract_valid { ctx.capacity.sampling_card > 0u && ctx.capacity.sampling_card <= detail::k_max_sampling_card && ctx.capacity.sampling_top_k > 0u && - ctx.capacity.sampling_top_k <= detail::k_max_sampling_top_k; + ctx.capacity.sampling_top_k <= detail::k_max_sampling_top_k && + (!runtime_ev.request.sampling_enabled || + (ctx.capacity.sampling_card >= + static_cast(model.moshi_lm.text_card) && + ctx.capacity.sampling_card >= + static_cast(model.moshi_lm.card) && + ctx.capacity.sampling_top_k >= + static_cast( + std::min(runtime_ev.request.sampling_text_top_k, + model.moshi_lm.text_card)) && + ctx.capacity.sampling_top_k >= + static_cast( + std::min(runtime_ev.request.sampling_audio_top_k, + model.moshi_lm.card)))); } }; @@ -1308,8 +1322,16 @@ struct guard_forced_text_token_valid { struct guard_forced_text_token_absent { bool operator()(const event::step_run &runtime_ev, - const action::context &ctx) const noexcept { - return !guard_forced_text_token_valid{}(runtime_ev, ctx); + const action::context &) const noexcept { + return runtime_ev.request.forced_text_token < 0; + } +}; + +struct guard_forced_text_token_invalid { + bool operator()(const event::step_run &runtime_ev, + const action::context &) const noexcept { + return runtime_ev.request.forced_text_token >= + runtime_ev.request.model.moshi_lm.text_card; } }; diff --git a/src/emel/speech/predictor/moshi/executor/sm.hpp b/src/emel/speech/predictor/moshi/executor/sm.hpp index ac663099..e136f446 100644 --- a/src/emel/speech/predictor/moshi/executor/sm.hpp +++ b/src/emel/speech/predictor/moshi/executor/sm.hpp @@ -638,6 +638,9 @@ struct model { , sml::state <= sml::state + sml::completion [ guard::guard_forced_text_sampling_config_invalid{} ] / action::effect_mark_graph_execution_unsupported{} + , sml::state <= sml::state + + sml::completion [ guard::guard_forced_text_token_invalid{} ] + / action::effect_mark_request_shape{} , sml::state <= sml::state + sml::completion [ guard::guard_text_logits_projection_bound_and_no_forced_token_argmax{} ] / action::effect_select_text_token{} diff --git a/src/emel/speech/tokenizer/moshi/guards.hpp b/src/emel/speech/tokenizer/moshi/guards.hpp index e5b953f8..f2b844b8 100644 --- a/src/emel/speech/tokenizer/moshi/guards.hpp +++ b/src/emel/speech/tokenizer/moshi/guards.hpp @@ -206,10 +206,32 @@ struct guard_detokenize_shape_valid { } }; -struct guard_detokenize_shape_invalid { +struct guard_detokenize_tokens_valid { bool operator()(const event::detokenize_run &runtime_ev, const action::context &ctx) const noexcept { - return !guard_detokenize_shape_valid{}(runtime_ev, ctx); + bool valid = runtime_ev.request.text_token >= 0 && + runtime_ev.request.text_token < ctx.config.text_initial_token; + for (const int32_t token : runtime_ev.request.audio_tokens) { + if (token < 0 || token >= ctx.config.audio_initial_token) { + valid = false; + } + } + return valid; + } +}; + +struct guard_detokenize_request_valid { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return guard_detokenize_shape_valid{}(runtime_ev, ctx) && + guard_detokenize_tokens_valid{}(runtime_ev, ctx); + } +}; + +struct guard_detokenize_request_invalid { + bool operator()(const event::detokenize_run &runtime_ev, + const action::context &ctx) const noexcept { + return !guard_detokenize_request_valid{}(runtime_ev, ctx); } }; @@ -223,7 +245,7 @@ struct guard_position_available { struct guard_position_overflow { bool operator()(const event::detokenize_run &runtime_ev, const action::context &ctx) const noexcept { - return guard_detokenize_shape_valid{}(runtime_ev, ctx) && + return guard_detokenize_request_valid{}(runtime_ev, ctx) && !guard_position_available{}(runtime_ev, ctx); } }; @@ -246,7 +268,7 @@ struct guard_use_generated_audio { struct guard_detokenize_valid_replace { bool operator()(const event::detokenize_run &runtime_ev, const action::context &ctx) const noexcept { - return guard_detokenize_shape_valid{}(runtime_ev, ctx) && + return guard_detokenize_request_valid{}(runtime_ev, ctx) && guard_position_available{}(runtime_ev, ctx) && guard_replace_generated_audio{}(runtime_ev, ctx); } @@ -255,7 +277,7 @@ struct guard_detokenize_valid_replace { struct guard_detokenize_valid_generated { bool operator()(const event::detokenize_run &runtime_ev, const action::context &ctx) const noexcept { - return guard_detokenize_shape_valid{}(runtime_ev, ctx) && + return guard_detokenize_request_valid{}(runtime_ev, ctx) && guard_position_available{}(runtime_ev, ctx) && guard_use_generated_audio{}(runtime_ev, ctx); } diff --git a/src/emel/speech/tokenizer/moshi/sm.hpp b/src/emel/speech/tokenizer/moshi/sm.hpp index 9a235770..35b81005 100644 --- a/src/emel/speech/tokenizer/moshi/sm.hpp +++ b/src/emel/speech/tokenizer/moshi/sm.hpp @@ -159,15 +159,15 @@ struct model { / action::effect_begin_detokenize{} , sml::state <= sml::state + sml::event - [ guard::guard_detokenize_shape_invalid{} ] + [ guard::guard_detokenize_request_invalid{} ] / action::effect_reject_detokenize{} , sml::state <= sml::state + sml::event - [ guard::guard_detokenize_shape_invalid{} ] + [ guard::guard_detokenize_request_invalid{} ] / action::effect_reject_detokenize{} , sml::state <= sml::state + sml::event - [ guard::guard_detokenize_shape_invalid{} ] + [ guard::guard_detokenize_request_invalid{} ] / action::effect_reject_detokenize{} , sml::state <= sml::state + sml::event [ guard::guard_position_overflow{} ] diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index fd047f79..e89e1cfa 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -414,7 +414,10 @@ void configure_q4_k_lm_contract(emel::model::data &model) { model.params.n_vocab = k_text_card; set_q4_k_matrix(model, "lm.text_emb.weight", k_dim, k_text_card + 1); set_q4_k_matrix(model, "lm.text_linear.weight", k_dim, k_text_card); - set_q4_k_matrix(model, "lm.emb.0.weight", k_dim, k_audio_card + 1); + for (int32_t codebook = 0; codebook < model.moshi_lm.n_q; ++codebook) { + set_q4_k_matrix(model, "lm.emb." + std::to_string(codebook) + ".weight", + k_dim, k_audio_card + 1); + } } } // namespace @@ -574,6 +577,22 @@ TEST_CASE("moshi lm contract requires every split depformer input projection") { CHECK(moshi::validate_execution_contract(*model) != k_none); } +TEST_CASE("moshi lm contract validates every audio embedding") { + auto loaded = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (loaded.model == nullptr) { + return; + } + + auto model = std::make_unique(*loaded.model); + auto *embedding = find_mutable_tensor(*model, "lm.emb.1.weight"); + REQUIRE(embedding != nullptr); + + SUBCASE("shape") { embedding->dims[0] += 1; } + SUBCASE("execution dtype") { embedding->type = 10; } + + CHECK(moshi::validate_execution_contract(*model) != k_none); +} + TEST_CASE("moshi lm contract binds only scheduled depformer weight sets") { auto loaded = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (loaded.model == nullptr) { diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 3649a3e5..a6ff4500 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -1100,6 +1100,38 @@ TEST_CASE("speech_moshi_executor_rejects_missing_capacity") { CHECK(err == emel::error::cast(moshi_executor::error::bind_failed)); } +TEST_CASE("speech_moshi_executor_rejects_undersized_sampling_capacity") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + + const auto rejected = [&fixture](const uint64_t sampling_card, + const uint64_t sampling_top_k) { + emel::kernel::sm kernel{}; + emel::logits::sampler::sm sampler{}; + auto dependencies = make_executor_dependencies(kernel, {}, &sampler); + dependencies.capacity.sampling_card = sampling_card; + dependencies.capacity.sampling_top_k = sampling_top_k; + moshi_executor::sm executor{dependencies}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.sampling_enabled = true; + init.sampling_audio_temperature = 0.8f; + init.sampling_text_temperature = 0.7f; + init.sampling_audio_top_k = 2; + init.sampling_text_top_k = 2; + init.sampling_seed = 1234u; + init.error_out = &err; + return !executor.process_event(init) && + err == emel::error::cast(moshi_executor::error::bind_failed); + }; + + CHECK(rejected(static_cast(fixture.model->moshi_lm.text_card - 1), + 2u)); + CHECK(rejected(moshi_executor::detail::k_max_sampling_card, 1u)); +} + TEST_CASE("speech_moshi_executor_models_zero_seed_and_top_k_clamp") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { @@ -2373,6 +2405,8 @@ TEST_CASE( step.forced_text_token = lm.text_card; CHECK_FALSE(moshi_executor::guard::guard_forced_text_token_valid{}( step_run, executor_ctx)); + CHECK_FALSE(moshi_executor::guard::guard_forced_text_token_absent{}( + step_run, executor_ctx)); float tensor_data = 0.0f; emel::model::data::tensor_record malformed_matrix{}; diff --git a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp index f836fe13..ad6c1306 100644 --- a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp +++ b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp @@ -112,14 +112,14 @@ TEST_CASE("speech Moshi tokenizer preserves complete provided frames") { const std::array first_input = {50, 51, 52}; const std::array second_input = {60, 61, 62}; const std::array third_input = {70, 71, 72}; - const std::array generated = {901, 902}; + const std::array generated = {91, 92}; REQUIRE(state.tokenize(first_input)); - REQUIRE(state.detokenize(900, generated)); + REQUIRE(state.detokenize(90, generated)); REQUIRE(state.tokenize(second_input)); - REQUIRE(state.detokenize(900, generated)); + REQUIRE(state.detokenize(90, generated)); REQUIRE(state.tokenize(third_input)); - REQUIRE(state.detokenize(900, generated)); + REQUIRE(state.detokenize(90, generated)); CHECK(state.produced); CHECK(state.text_out == 60); @@ -207,6 +207,23 @@ TEST_CASE("speech Moshi tokenizer rejects invalid public audio tokens before " CHECK(state.model_tokens == std::array{100, 200, 200}); } +TEST_CASE("speech Moshi tokenizer rejects invalid generated tokens before " + "commit") { + standard_fixture state; + REQUIRE(state.initialize()); + + REQUIRE(state.tokenize()); + const std::array invalid_audio = {11, 200}; + CHECK(state.detokenize(10, invalid_audio)); + CHECK(state.err == error_code(moshi::error::request_shape)); + CHECK(state.machine.is(sml::state)); + + const std::array valid_audio = {11, 12}; + CHECK(state.detokenize(100, valid_audio)); + CHECK(state.err == error_code(moshi::error::request_shape)); + CHECK(state.machine.is(sml::state)); +} + TEST_CASE("speech Moshi tokenizer masks initial delayed audio explicitly") { standard_fixture state{2}; REQUIRE(state.initialize()); From ca3a7eeb1fac2ae9bd655bafaf2b9ad41f1a055a Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 13:44:35 -0500 Subject: [PATCH 59/61] fix remaining model and sampler validation --- scripts/quality_gates.sh | 1 + snapshots/lint/clang_format.txt | 3 - src/emel/logits/sampler/guards.hpp | 81 ++++++---- src/emel/logits/sampler/sm.hpp | 15 +- src/emel/model/moshi/detail.cpp | 11 +- src/emel/speech/predictor/moshi/guards.hpp | 3 + src/emel/speech/tokenizer/moshi/guards.hpp | 21 ++- tests/logits/sampler/pipeline_tests.cpp | 138 ++++++++++++------ tests/model/moshi/binding_tests.cpp | 32 ++++ .../predictor/moshi_lifecycle_tests.cpp | 16 ++ .../tokenizer/moshi/lifecycle_tests.cpp | 13 ++ tools/bench/moshi_gguf_convert.py | 21 ++- tools/bench/personaplex_compare_tests.cpp | 10 ++ tools/bench/quality_gates_tests.cpp | 15 +- 14 files changed, 283 insertions(+), 97 deletions(-) diff --git a/scripts/quality_gates.sh b/scripts/quality_gates.sh index de92eb2e..c8a76c3f 100755 --- a/scripts/quality_gates.sh +++ b/scripts/quality_gates.sh @@ -859,6 +859,7 @@ infer_quality_gate_scope() { tests/speech/codec/mimi*|tests/speech/predictor/*|\ tests/speech/tokenizer/moshi/*|\ tools/bench/personaplex*|tools/bench/speech/personaplex*|\ + tools/bench/moshi_gguf_convert.py|scripts/setup_moshi_cpp_reference.sh|\ scripts/bench_personaplex_compare.sh) add_bench_suite speech_dialogue_moshi "scope path=$file" ;; diff --git a/snapshots/lint/clang_format.txt b/snapshots/lint/clang_format.txt index 6df20403..5b417438 100644 --- a/snapshots/lint/clang_format.txt +++ b/snapshots/lint/clang_format.txt @@ -290,8 +290,6 @@ src/emel/logits/sampler/actions.hpp src/emel/logits/sampler/context.hpp src/emel/logits/sampler/errors.hpp src/emel/logits/sampler/events.hpp -src/emel/logits/sampler/guards.hpp -src/emel/logits/sampler/sm.hpp src/emel/logits/validator/actions.hpp src/emel/logits/validator/context.hpp src/emel/logits/validator/errors.hpp @@ -585,7 +583,6 @@ tests/kernel/aarch64_tests.cpp tests/kernel/lifecycle_tests.cpp tests/kernel/test_helpers.hpp tests/kernel/x86_64_tests.cpp -tests/logits/sampler/pipeline_tests.cpp tests/logits/validator/validator_tests.cpp tests/memory/hybrid/lifecycle_tests.cpp tests/memory/kv/lifecycle_tests.cpp diff --git a/src/emel/logits/sampler/guards.hpp b/src/emel/logits/sampler/guards.hpp index 1f81f2cf..f04fb614 100644 --- a/src/emel/logits/sampler/guards.hpp +++ b/src/emel/logits/sampler/guards.hpp @@ -1,130 +1,140 @@ #pragma once +#include + #include "emel/logits/sampler/context.hpp" #include "emel/logits/sampler/events.hpp" namespace emel::logits::sampler::guard { struct valid_config { - bool operator()(const event::configure_runtime & ev) const noexcept { + bool operator()(const event::configure_runtime &ev) const noexcept { return ev.request.sampler_count > 0; } }; struct invalid_config { - bool operator()(const event::configure_runtime & ev) const noexcept { + bool operator()(const event::configure_runtime &ev) const noexcept { return !valid_config{}(ev); } }; struct request_has_valid_sizes { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return ev.request.vocab_size > 0 && ev.request.candidate_capacity >= ev.request.vocab_size; } }; struct context_has_valid_sampler_table { - bool operator()(const event::sample_logits_runtime &, const action::context & ctx) const noexcept { + bool operator()(const event::sample_logits_runtime &, + const action::context &ctx) const noexcept { return ctx.sampler_count > 0 && ctx.sampler_fns != nullptr; } }; struct valid_request { - bool operator()(const event::sample_logits_runtime & ev, const action::context & ctx) const noexcept { - return request_has_valid_sizes{}(ev) && context_has_valid_sampler_table{}(ev, ctx); + bool operator()(const event::sample_logits_runtime &ev, + const action::context &ctx) const noexcept { + return request_has_valid_sizes{}(ev) && + context_has_valid_sampler_table{}(ev, ctx); } }; struct invalid_request { - bool operator()(const event::sample_logits_runtime & ev, const action::context & ctx) const noexcept { + bool operator()(const event::sample_logits_runtime &ev, + const action::context &ctx) const noexcept { return !valid_request{}(ev, ctx); } }; struct preselected_token_valid { - bool operator()(const event::sample_preselected_runtime & ev) const noexcept { - return ev.request.vocab_size > 0 && - ev.request.selected_token_out >= 0 && + bool operator()(const event::sample_preselected_runtime &ev) const noexcept { + return ev.request.vocab_size > 0 && ev.request.selected_token_out >= 0 && ev.request.selected_token_out < ev.request.vocab_size; } }; struct preselected_token_invalid { - bool operator()(const event::sample_preselected_runtime & ev) const noexcept { + bool operator()(const event::sample_preselected_runtime &ev) const noexcept { return !preselected_token_valid{}(ev); } }; struct has_more_samplers { - bool operator()(const event::sample_logits_runtime & ev, const action::context & ctx) const noexcept { + bool operator()(const event::sample_logits_runtime &ev, + const action::context &ctx) const noexcept { return ev.ctx.sampler_index < ctx.sampler_count; } }; struct no_more_samplers { - bool operator()(const event::sample_logits_runtime & ev, const action::context & ctx) const noexcept { + bool operator()(const event::sample_logits_runtime &ev, + const action::context &ctx) const noexcept { return ev.ctx.sampler_index >= ctx.sampler_count; } }; struct sampler_fn_available { - bool operator()(const event::sample_logits_runtime & ev, const action::context & ctx) const noexcept { + bool operator()(const event::sample_logits_runtime &ev, + const action::context &ctx) const noexcept { return static_cast(ctx.sampler_fns[ev.ctx.sampler_index]); } }; struct sampler_fn_missing { - bool operator()(const event::sample_logits_runtime & ev, const action::context & ctx) const noexcept { + bool operator()(const event::sample_logits_runtime &ev, + const action::context &ctx) const noexcept { return !sampler_fn_available{}(ev, ctx); } }; struct sampler_call_succeeded { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return ev.ctx.sampler_call_error == emel::error::cast(error::none); } }; struct sampler_call_failed { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return ev.ctx.sampler_call_error != emel::error::cast(error::none); } }; struct candidate_count_valid { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { - return ev.ctx.candidate_count > 0 && ev.ctx.candidate_count <= ev.request.vocab_size; + bool operator()(const event::sample_logits_runtime &ev) const noexcept { + return ev.ctx.candidate_count > 0 && + ev.ctx.candidate_count <= ev.request.vocab_size; } }; struct candidate_count_invalid { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return !candidate_count_valid{}(ev); } }; struct sampler_call_succeeded_with_valid_candidate_count { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return sampler_call_succeeded{}(ev) && candidate_count_valid{}(ev); } }; struct sampler_call_succeeded_with_invalid_candidate_count { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return sampler_call_succeeded{}(ev) && candidate_count_invalid{}(ev); } }; struct selected_token_valid { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return ev.request.selected_token_out >= 0 && ev.request.selected_token_out < ev.request.vocab_size; } }; struct selected_token_missing_or_invalid { - bool operator()(const event::sample_logits_runtime & ev) const noexcept { + bool operator()(const event::sample_logits_runtime &ev) const noexcept { return !selected_token_valid{}(ev); } }; @@ -134,8 +144,9 @@ struct temperature_top_k_request_valid { operator()(const event::sample_temperature_top_k_runtime &ev) const noexcept { const auto &request = ev.request; constexpr uint32_t random_modulus = 2147483647u; - return request.card > 0 && request.temperature > 0.0f && - request.top_k > 0 && request.top_k <= request.card && + return request.card > 0 && std::isfinite(request.temperature) && + request.temperature > 0.0f && request.top_k > 0 && + request.top_k <= request.card && request.logits.size() >= static_cast(request.card) && request.sorted_indices.size() >= static_cast(request.card) && request.top_probabilities.size() >= @@ -145,6 +156,22 @@ struct temperature_top_k_request_valid { } }; +struct temperature_top_k_selected_token_valid { + bool + operator()(const event::sample_temperature_top_k_runtime &ev) const noexcept { + return ev.request.selected_token_out >= 0 && + ev.request.selected_token_out < ev.request.card && + std::isfinite(ev.request.selected_score_out); + } +}; + +struct temperature_top_k_selected_token_invalid { + bool + operator()(const event::sample_temperature_top_k_runtime &ev) const noexcept { + return !temperature_top_k_selected_token_valid{}(ev); + } +}; + struct temperature_top_k_request_invalid { bool operator()(const event::sample_temperature_top_k_runtime &ev) const noexcept { @@ -152,4 +179,4 @@ struct temperature_top_k_request_invalid { } }; -} // namespace emel::logits::sampler::guard +} // namespace emel::logits::sampler::guard diff --git a/src/emel/logits/sampler/sm.hpp b/src/emel/logits/sampler/sm.hpp index 4706c877..1a44f93e 100644 --- a/src/emel/logits/sampler/sm.hpp +++ b/src/emel/logits/sampler/sm.hpp @@ -122,6 +122,11 @@ struct model { / action::select_temperature_top_k , sml::state <= sml::state + sml::completion + [ guard::temperature_top_k_selected_token_valid{} ] + , sml::state <= sml::state + + sml::completion + [ guard::temperature_top_k_selected_token_invalid{} ] + / action::mark_invalid_request //------------------------------------------------------------------------------// , sml::state <= sml::state + sml::completion @@ -189,21 +194,21 @@ struct sm : public emel::sm { sm() : base_type() {} - bool process_event(const event::configure & ev) { + bool process_event(const event::configure &ev) { event::configure_ctx ctx{}; event::configure_runtime runtime{ev, ctx}; const bool accepted = base_type::process_event(runtime); return accepted && ctx.err == emel::error::cast(error::none); } - bool process_event(const event::sample_logits & ev) { + bool process_event(const event::sample_logits &ev) { event::sample_logits_ctx ctx{}; event::sample_logits_runtime runtime{ev, ctx}; const bool accepted = base_type::process_event(runtime); return accepted && ctx.err == emel::error::cast(error::none); } - bool process_event(const event::sample_preselected & ev) { + bool process_event(const event::sample_preselected &ev) { event::sample_preselected_ctx ctx{}; event::sample_preselected_runtime runtime{ev, ctx}; const bool accepted = base_type::process_event(runtime); @@ -217,9 +222,9 @@ struct sm : public emel::sm { return accepted && ctx.err == emel::error::cast(error::none); } - private: +private: }; using Sampler = sm; -} // namespace emel::logits::sampler +} // namespace emel::logits::sampler diff --git a/src/emel/model/moshi/detail.cpp b/src/emel/model/moshi/detail.cpp index 545ec429..94f25faf 100644 --- a/src/emel/model/moshi/detail.cpp +++ b/src/emel/model/moshi/detail.cpp @@ -830,7 +830,10 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, const auto *depformer_text_embedding = find_tensor(model_data, "lm.depformer_text_emb.weight"); - if (depformer_text_embedding == nullptr) { + if (depformer_text_embedding == nullptr || + !require_lm_embedding_tensor_shape(model_data, + "lm.depformer_text_emb.weight", + {lm.depformer_dim, text_card + 1})) { return emel::error::cast(emel::model::loader::error::model_invalid); } contract_out.depformer_text_embedding = tensor_view{ @@ -886,7 +889,11 @@ emel::error::type validate_lm_contract(const emel::model::data &model_data, } const auto *audio_embedding = find_tensor( model_data, std::string_view{name, static_cast(written)}); - if (audio_embedding == nullptr) { + if (audio_embedding == nullptr || + !require_lm_embedding_tensor_shape( + model_data, + std::string_view{name, static_cast(written)}, + {lm.depformer_dim, card + 1})) { return emel::error::cast(emel::model::loader::error::model_invalid); } contract_out.depformer_audio_embeddings[static_cast( diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index 6e09b9a9..c49de4c2 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -15,6 +15,9 @@ struct guard_bind_contract_valid { const action::context &ctx) const noexcept { const auto &model = runtime_ev.request.model; const auto &lm = model.moshi_lm; + if (lm.delay_count > lm.delays.size()) { + return false; + } int32_t max_delay = 0; for (uint32_t index = 0; index < lm.delay_count; ++index) { if (lm.delays[index] > max_delay) { diff --git a/src/emel/speech/tokenizer/moshi/guards.hpp b/src/emel/speech/tokenizer/moshi/guards.hpp index f2b844b8..794179bd 100644 --- a/src/emel/speech/tokenizer/moshi/guards.hpp +++ b/src/emel/speech/tokenizer/moshi/guards.hpp @@ -169,9 +169,24 @@ struct guard_restore_valid { const action::context &ctx) const noexcept { const uint64_t elements = static_cast(ctx.config.cache_rows) * static_cast(ctx.config.codebooks); - return elements == ev.column_major_cache.size() && ev.offset >= 0 && - ev.offset <= std::numeric_limits::max() - - static_cast(ctx.config.maximum_delay); + bool valid = + elements == ev.column_major_cache.size() && ev.offset >= 0 && + ev.offset <= std::numeric_limits::max() - + static_cast(ctx.config.maximum_delay); + for (size_t index = 0; index < ev.column_major_cache.size(); ++index) { + const int32_t token = ev.column_major_cache[index]; + const bool sentinel = token == ctx.config.token_zero || + token == ctx.config.token_ungenerated; + const size_t codebook = + index / static_cast(ctx.config.cache_rows); + const int32_t upper_bound = codebook == 0u + ? ctx.config.text_initial_token + : ctx.config.audio_initial_token; + if (!sentinel && (token < 0 || token >= upper_bound)) { + valid = false; + } + } + return valid; } }; diff --git a/tests/logits/sampler/pipeline_tests.cpp b/tests/logits/sampler/pipeline_tests.cpp index 932c0345..8bd0fd6f 100644 --- a/tests/logits/sampler/pipeline_tests.cpp +++ b/tests/logits/sampler/pipeline_tests.cpp @@ -1,5 +1,8 @@ #include "doctest/doctest.h" +#include +#include + #include "emel/emel.h" #include "emel/error/error.hpp" #include "emel/gbnf/detail.hpp" @@ -8,10 +11,8 @@ namespace { -emel::error::type sampler_shift_scores(int32_t &, - float & candidate_scores, - int32_t & candidate_count, - int32_t &) { +emel::error::type sampler_shift_scores(int32_t &, float &candidate_scores, + int32_t &candidate_count, int32_t &) { for (int32_t i = 0; i < candidate_count; ++i) { (&candidate_scores)[i] = -1.0f; } @@ -19,10 +20,10 @@ emel::error::type sampler_shift_scores(int32_t &, return emel::error::cast(emel::logits::sampler::error::none); } -emel::error::type sampler_select_argmax(int32_t & candidate_ids, - float & candidate_scores, - int32_t & candidate_count, - int32_t & selected_token_out) { +emel::error::type sampler_select_argmax(int32_t &candidate_ids, + float &candidate_scores, + int32_t &candidate_count, + int32_t &selected_token_out) { int32_t best_idx = 0; float best_score = (&candidate_scores)[0]; for (int32_t i = 1; i < candidate_count; ++i) { @@ -35,46 +36,38 @@ emel::error::type sampler_select_argmax(int32_t & candidate_ids, return emel::error::cast(emel::logits::sampler::error::none); } -emel::error::type sampler_select_fixed(int32_t &, - float &, - int32_t &, - int32_t & selected_token_out) { +emel::error::type sampler_select_fixed(int32_t &, float &, int32_t &, + int32_t &selected_token_out) { selected_token_out = 7; return emel::error::cast(emel::logits::sampler::error::none); } -emel::error::type sampler_select_first(int32_t & candidate_ids, - float &, - int32_t &, - int32_t & selected_token_out) { +emel::error::type sampler_select_first(int32_t &candidate_ids, float &, + int32_t &, int32_t &selected_token_out) { selected_token_out = (&candidate_ids)[0]; return emel::error::cast(emel::logits::sampler::error::none); } -emel::error::type sampler_error(int32_t &, - float &, - int32_t &, - int32_t &) { +emel::error::type sampler_error(int32_t &, float &, int32_t &, int32_t &) { return emel::error::cast(emel::logits::sampler::error::backend_error); } -emel::error::type sampler_set_invalid_candidate_count(int32_t &, - float &, - int32_t & candidate_count, +emel::error::type sampler_set_invalid_candidate_count(int32_t &, float &, + int32_t &candidate_count, int32_t &) { candidate_count = 0; return emel::error::cast(emel::logits::sampler::error::none); } -bool configure_sampler_chain(emel::logits::sampler::sm & machine, - emel::logits::sampler::fn & sampler_fns, - int32_t sampler_count, - emel::error::type & err) { - emel::logits::sampler::event::configure request{sampler_fns, sampler_count, err}; +bool configure_sampler_chain(emel::logits::sampler::sm &machine, + emel::logits::sampler::fn &sampler_fns, + int32_t sampler_count, emel::error::type &err) { + emel::logits::sampler::event::configure request{sampler_fns, sampler_count, + err}; return machine.process_event(request); } -} // namespace +} // namespace TEST_CASE("sampler pipeline selects token via selector sampler") { float logits[3] = {0.0f, 0.1f, 0.2f}; @@ -98,7 +91,8 @@ TEST_CASE("sampler pipeline selects token via selector sampler") { CHECK(selected == 1); } -TEST_CASE("sampler pipeline reports invalid request when no samplers are configured") { +TEST_CASE("sampler pipeline reports invalid request when no samplers are " + "configured") { emel::logits::sampler::sm machine{}; float logits[2] = {1.0f, 2.0f}; @@ -111,17 +105,20 @@ TEST_CASE("sampler pipeline reports invalid request when no samplers are configu logits[0], 2, ids[0], scores[0], 2, selected, err}; CHECK(!machine.process_event(request)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == -1); } TEST_CASE("sampler configure rejects invalid sampler count") { emel::logits::sampler::sm machine{}; - emel::logits::sampler::fn sampler = emel::logits::sampler::fn::from(); + emel::logits::sampler::fn sampler = + emel::logits::sampler::fn::from(); emel::error::type err = emel::error::cast(emel::logits::sampler::error::none); CHECK_FALSE(configure_sampler_chain(machine, sampler, 0, err)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); } TEST_CASE("sampler configure can replace the sampler chain") { @@ -156,11 +153,13 @@ TEST_CASE("sampler configure can replace the sampler chain") { CHECK(selected == 0); } -TEST_CASE("sampler pipeline accepts valid preselected token without sampler chain") { +TEST_CASE( + "sampler pipeline accepts valid preselected token without sampler chain") { emel::logits::sampler::sm machine{}; int32_t selected = 2; - emel::error::type err = emel::error::cast(emel::logits::sampler::error::backend_error); + emel::error::type err = + emel::error::cast(emel::logits::sampler::error::backend_error); emel::logits::sampler::event::sample_preselected request{3, selected, err}; @@ -178,7 +177,8 @@ TEST_CASE("sampler pipeline rejects invalid preselected token") { emel::logits::sampler::event::sample_preselected request{3, selected, err}; CHECK(!machine.process_event(request)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == 7); } @@ -195,17 +195,20 @@ TEST_CASE("sampler pipeline reports invalid arguments") { logits[0], 2, ids[0], scores[0], 1, selected, err}; CHECK(!machine.process_event(request)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == -1); } TEST_CASE("sampler pipeline reports invalid context sampler table") { emel::logits::sampler::sm machine{}; - emel::logits::sampler::fn sampler = emel::logits::sampler::fn::from(); + emel::logits::sampler::fn sampler = + emel::logits::sampler::fn::from(); emel::error::type err = emel::error::cast(emel::logits::sampler::error::none); CHECK_FALSE(configure_sampler_chain(machine, sampler, 0, err)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); } TEST_CASE("sampler pipeline reports missing sampler function") { @@ -223,7 +226,8 @@ TEST_CASE("sampler pipeline reports missing sampler function") { logits[0], 1, ids[0], scores[0], 1, selected, err}; CHECK(!machine.process_event(request)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == -1); } @@ -248,7 +252,8 @@ TEST_CASE("sampler pipeline reports sampler errors") { CHECK(selected == -1); } -TEST_CASE("sampler pipeline reports invalid request when no selector sampler sets a token") { +TEST_CASE("sampler pipeline reports invalid request when no selector sampler " + "sets a token") { float logits[2] = {0.0f, 0.1f}; int32_t ids[2] = {}; float scores[2] = {}; @@ -265,11 +270,13 @@ TEST_CASE("sampler pipeline reports invalid request when no selector sampler set logits[0], 2, ids[0], scores[0], 2, selected, err}; CHECK(!machine.process_event(request)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == -1); } -TEST_CASE("sampler pipeline reports invalid request when sampler sets invalid candidate_count") { +TEST_CASE("sampler pipeline reports invalid request when sampler sets invalid " + "candidate_count") { float logits[3] = {0.0f, 0.1f, 0.2f}; int32_t ids[3] = {}; float scores[3] = {}; @@ -286,11 +293,13 @@ TEST_CASE("sampler pipeline reports invalid request when sampler sets invalid ca logits[0], 3, ids[0], scores[0], 3, selected, err}; CHECK(!machine.process_event(request)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == -1); } -TEST_CASE("sampler pipeline reports invalid request when selector picks out-of-range token") { +TEST_CASE("sampler pipeline reports invalid request when selector picks " + "out-of-range token") { float logits[3] = {0.0f, 0.1f, 0.2f}; int32_t ids[3] = {}; float scores[3] = {}; @@ -307,7 +316,8 @@ TEST_CASE("sampler pipeline reports invalid request when selector picks out-of-r logits[0], 3, ids[0], scores[0], 3, selected, err}; CHECK(!machine.process_event(request)); - CHECK(err == emel::error::cast(emel::logits::sampler::error::invalid_request)); + CHECK(err == + emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == 7); } @@ -420,3 +430,39 @@ TEST_CASE("sampler rejects Park-Miller zero-state seeds") { emel::error::cast(emel::logits::sampler::error::invalid_request)); CHECK(selected == -1); } + +TEST_CASE("sampler rejects non-finite temperature and unselectable logits") { + const auto rejected = [](std::array logits, + const float temperature) { + std::array sorted_indices{}; + std::array top_probabilities{}; + std::array top_indices{}; + uint32_t random_state = 1234u; + int32_t selected = -1; + float score = 0.0f; + emel::error::type err = + emel::error::cast(emel::logits::sampler::error::none); + emel::logits::sampler::event::sample_temperature_top_k request{ + logits, + 2, + temperature, + 1, + sorted_indices, + top_probabilities, + top_indices, + random_state, + selected, + score, + err}; + emel::logits::sampler::sm machine{}; + return !machine.process_event(request) && + err == emel::error::cast( + emel::logits::sampler::error::invalid_request) && + selected == -1; + }; + CHECK(rejected({1.0f, 2.0f}, std::numeric_limits::infinity())); + CHECK(rejected({std::numeric_limits::quiet_NaN(), 2.0f}, 0.8f)); + CHECK(rejected({-std::numeric_limits::infinity(), + -std::numeric_limits::infinity()}, + 0.8f)); +} diff --git a/tests/model/moshi/binding_tests.cpp b/tests/model/moshi/binding_tests.cpp index e89e1cfa..e24d5495 100644 --- a/tests/model/moshi/binding_tests.cpp +++ b/tests/model/moshi/binding_tests.cpp @@ -418,6 +418,19 @@ void configure_q4_k_lm_contract(emel::model::data &model) { set_q4_k_matrix(model, "lm.emb." + std::to_string(codebook) + ".weight", k_dim, k_audio_card + 1); } + set_matrix_tensor(model, "lm.depformer_text_emb.weight", + emel::kernel::detail::dtype_f32, + model.moshi_lm.depformer_dim, k_text_card + 1, + dense_storage_bytes(model.moshi_lm.depformer_dim, + k_text_card + 1, sizeof(uint32_t))); + for (int32_t codebook = 0; codebook < model.moshi_lm.dep_q - 1; ++codebook) { + set_matrix_tensor( + model, "lm.depformer_emb." + std::to_string(codebook) + ".weight", + emel::kernel::detail::dtype_f32, model.moshi_lm.depformer_dim, + k_audio_card + 1, + dense_storage_bytes(model.moshi_lm.depformer_dim, k_audio_card + 1, + sizeof(uint32_t))); + } } } // namespace @@ -593,6 +606,25 @@ TEST_CASE("moshi lm contract validates every audio embedding") { CHECK(moshi::validate_execution_contract(*model) != k_none); } +TEST_CASE("moshi lm contract validates depformer embeddings") { + auto loaded = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (loaded.model == nullptr) { + return; + } + auto model = std::make_unique(*loaded.model); + SUBCASE("text shape") { + auto *tensor = find_mutable_tensor(*model, "lm.depformer_text_emb.weight"); + REQUIRE(tensor != nullptr); + tensor->dims[0] += 1; + } + SUBCASE("audio dtype") { + auto *tensor = find_mutable_tensor(*model, "lm.depformer_emb.0.weight"); + REQUIRE(tensor != nullptr); + tensor->type = 10; + } + CHECK(moshi::validate_execution_contract(*model) != k_none); +} + TEST_CASE("moshi lm contract binds only scheduled depformer weight sets") { auto loaded = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (loaded.model == nullptr) { diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index a6ff4500..5dc9f487 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -490,6 +490,22 @@ TEST_CASE("speech_moshi_predictor_rejects_missing_token_policy") { CHECK(err == emel::error::cast(moshi::error::bind_failed)); } +TEST_CASE("speech_moshi_predictor_bounds_delay_count_before_scanning") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + auto model = std::make_unique(*fixture.model); + model->moshi_lm.delay_count = + static_cast(model->moshi_lm.delays.size() + 1u); + moshi::event::initialize request{*model}; + moshi::event::initialize_ctx request_ctx{}; + moshi::event::initialize_run runtime{request, request_ctx}; + emel::memory::hybrid::sm memory{}; + moshi::action::context ctx{memory}; + CHECK_FALSE(moshi::guard::guard_bind_contract_valid{}(runtime, ctx)); +} + TEST_CASE("speech_moshi_generator_personaplex_uses_model_inference_codebooks") { auto model = std::make_unique(); model->moshi_lm.n_q = 16; diff --git a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp index ad6c1306..e4872fca 100644 --- a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp +++ b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp @@ -263,6 +263,19 @@ TEST_CASE("speech Moshi tokenizer restores column-major voice cache") { CHECK(state.model_tokens == std::array{12, 22, 200}); } +TEST_CASE("speech Moshi tokenizer rejects invalid restored cache tokens") { + standard_fixture state; + REQUIRE(state.initialize()); + std::array column_major{}; + column_major[0] = 100; + CHECK(state.machine.process_event(moshi::event::restore_cache{ + .column_major_cache = std::span{column_major}, + .offset = 0, + .error_out = state.err, + })); + CHECK(state.err == error_code(moshi::error::request_shape)); +} + TEST_CASE( "speech Moshi tokenizer does not publish restored ungenerated output") { standard_fixture state; diff --git a/tools/bench/moshi_gguf_convert.py b/tools/bench/moshi_gguf_convert.py index 42640da0..54560b7d 100644 --- a/tools/bench/moshi_gguf_convert.py +++ b/tools/bench/moshi_gguf_convert.py @@ -596,11 +596,24 @@ def require_block(prefix: str, layer: int, with_gating: bool) -> None: f"{layer_count} layer tensors present)") require_block("lm.transformer", layer, with_gating=True) if config["dep_q"] > 0: - expected_depformer_weights = depformer_weight_count(config) - if count_prefixed(infos, "lm.depformer_in.") != expected_depformer_weights: + schedule = config.get("depformer_weights_per_step_schedule") + if schedule: + required_depformer_indices = set(schedule) + elif config.get("depformer_multi_linear"): + required_depformer_indices = set(range(config["dep_q"])) + else: + required_depformer_indices = {0} + required_depformer_names = { + f"lm.depformer_in.{index}.weight" + for index in required_depformer_indices + } + present_depformer_names = { + info.name for info in infos if info.name.startswith("lm.depformer_in.") + } + if present_depformer_names != required_depformer_names: raise ValueError( - "lm.depformer_in.* count does not match depformer weight count " - f"{expected_depformer_weights}") + "lm.depformer_in.* names do not match scheduled weight indices " + f"{sorted(required_depformer_indices)}") if count_prefixed(infos, "lm.linears.") != config["dep_q"]: raise ValueError("lm.linears.* count does not match config dep_q") # The C++ contract also requires the depformer text-embedding family for diff --git a/tools/bench/personaplex_compare_tests.cpp b/tools/bench/personaplex_compare_tests.cpp index 1d57a522..1ae782ce 100644 --- a/tools/bench/personaplex_compare_tests.cpp +++ b/tools/bench/personaplex_compare_tests.cpp @@ -182,6 +182,16 @@ TEST_CASE("personaplex conversion injects its inference contract") { CHECK(command_exit_code(command) == 0); } +TEST_CASE("personaplex converter checks exact sparse depformer weights") { + const std::string converter_source = + read_file(repo_root() / "tools" / "bench" / "moshi_gguf_convert.py"); + CHECK(converter_source.find("required_depformer_indices = set(schedule)") != + std::string::npos); + CHECK(converter_source.find( + "present_depformer_names != required_depformer_names") != + std::string::npos); +} + TEST_CASE( "personaplex runtime orchestration is owned by the generic generator") { const auto generator_machine = diff --git a/tools/bench/quality_gates_tests.cpp b/tools/bench/quality_gates_tests.cpp index bbb23d8a..63281b8b 100644 --- a/tools/bench/quality_gates_tests.cpp +++ b/tools/bench/quality_gates_tests.cpp @@ -366,7 +366,8 @@ TEST_CASE("bench script routes Moshi LM suite through the wrapper") { std::string::npos); } -TEST_CASE("quality gates route PersonaPlex changes through end-to-end compare") { +TEST_CASE( + "quality gates route PersonaPlex changes through end-to-end compare") { const std::string script = read_file(repo_root() / "scripts" / "quality_gates.sh"); @@ -375,12 +376,13 @@ TEST_CASE("quality gates route PersonaPlex changes through end-to-end compare") CHECK(script.find("speech_dialogue_moshi)") != std::string::npos); CHECK(script.find("scripts/bench_personaplex_compare.sh") != std::string::npos); - CHECK(script.find("QUALITY_GATES_PERSONAPLEX_FRAMES") != - std::string::npos); - CHECK(script.find("QUALITY_GATES_PERSONAPLEX_AUDIO") != - std::string::npos); + CHECK(script.find("QUALITY_GATES_PERSONAPLEX_FRAMES") != std::string::npos); + CHECK(script.find("QUALITY_GATES_PERSONAPLEX_AUDIO") != std::string::npos); CHECK(script.find("--audio \"$QUALITY_GATES_PERSONAPLEX_AUDIO\"") != std::string::npos); + CHECK(script.find("tools/bench/moshi_gguf_convert.py|") != std::string::npos); + CHECK(script.find("scripts/setup_moshi_cpp_reference.sh|") != + std::string::npos); } TEST_CASE("benchmark defaults stay bounded for routine quality gates") { @@ -523,8 +525,7 @@ TEST_CASE( std::string::npos); CHECK(helper.find("gbnf_rule_parser") != std::string::npos); CHECK(helper.find("kernel_aarch64") != std::string::npos); - const std::size_t parallel_matmul_priority = - helper.find("parallel_matmul"); + const std::size_t parallel_matmul_priority = helper.find("parallel_matmul"); const std::size_t manifest_expansion = helper.find("while IFS= read -r line"); REQUIRE(parallel_matmul_priority != std::string::npos); REQUIRE(manifest_expansion != std::string::npos); From 918e0a0d2eccfa5cd5ee112650ea0424491dda82 Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 14:18:08 -0500 Subject: [PATCH 60/61] tighten speech initialization validation --- .../predictor/moshi/executor/guards.hpp | 4 ++ src/emel/speech/predictor/moshi/guards.hpp | 3 + src/emel/speech/tokenizer/moshi/guards.hpp | 4 +- .../predictor/moshi_lifecycle_tests.cpp | 55 +++++++++++++++++++ .../tokenizer/moshi/lifecycle_tests.cpp | 29 ++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/emel/speech/predictor/moshi/executor/guards.hpp b/src/emel/speech/predictor/moshi/executor/guards.hpp index abbd0b91..29a99c70 100644 --- a/src/emel/speech/predictor/moshi/executor/guards.hpp +++ b/src/emel/speech/predictor/moshi/executor/guards.hpp @@ -57,6 +57,10 @@ struct guard_bind_contract_valid { ctx.policy.sampling_modulus > 1u && ctx.policy.zero_seed_state % ctx.policy.sampling_modulus != 0u && ctx.policy.token_zero < 0 && ctx.capacity.hidden_dim > 0u && + ctx.capacity.hidden_dim >= + static_cast(model.moshi_lm.dim) && + ctx.capacity.hidden_dim >= + static_cast(model.moshi_lm.depformer_dim) && ctx.capacity.hidden_dim <= detail::k_max_hidden_dim && ctx.capacity.temporal_context > 0u && ctx.capacity.temporal_context <= detail::k_max_temporal_context && diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index c49de4c2..eb447862 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -20,6 +20,9 @@ struct guard_bind_contract_valid { } int32_t max_delay = 0; for (uint32_t index = 0; index < lm.delay_count; ++index) { + if (lm.delays[index] < 0) { + return false; + } if (lm.delays[index] > max_delay) { max_delay = lm.delays[index]; } diff --git a/src/emel/speech/tokenizer/moshi/guards.hpp b/src/emel/speech/tokenizer/moshi/guards.hpp index 794179bd..c066888c 100644 --- a/src/emel/speech/tokenizer/moshi/guards.hpp +++ b/src/emel/speech/tokenizer/moshi/guards.hpp @@ -18,7 +18,9 @@ struct guard_configuration_valid { config.delayed_audio_codebooks <= 0 || config.delayed_audio_codebooks > config.generated_audio_codebooks || config.cache_rows <= 0 || config.maximum_delay < 0 || - config.initial_delay_frames < 0 || config.audio_initial_token <= 0 || + config.initial_delay_frames < 0 || config.text_initial_token <= 0 || + config.audio_initial_token <= 0 || config.token_zero >= 0 || + config.token_ungenerated >= 0 || config.token_zero == config.token_ungenerated || config.delays.size() < static_cast(config.codebooks)) { return false; diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 5dc9f487..67c90999 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -506,6 +506,25 @@ TEST_CASE("speech_moshi_predictor_bounds_delay_count_before_scanning") { CHECK_FALSE(moshi::guard::guard_bind_contract_valid{}(runtime, ctx)); } +TEST_CASE("speech_moshi_predictor_rejects_negative_model_delays") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + auto model = std::make_unique(*fixture.model); + REQUIRE(model->moshi_lm.delay_count > 1u); + model->moshi_lm.delays[1] = -1; + recording_graph_executor graph{}; + emel::memory::hybrid::sm memory{}; + moshi::sm predictor{make_predictor_dependencies(graph, memory)}; + emel::error::type err = k_no_error; + moshi::event::initialize request{*model}; + configure_predictor_initialize(request); + request.error_out = &err; + CHECK_FALSE(predictor.process_event(request)); + CHECK(err == emel::error::cast(moshi::error::bind_failed)); +} + TEST_CASE("speech_moshi_generator_personaplex_uses_model_inference_codebooks") { auto model = std::make_unique(); model->moshi_lm.n_q = 16; @@ -843,6 +862,12 @@ TEST_CASE( CHECK(moshi_executor::guard::guard_bound_root_operands_supported{}(runtime_ev, ctx)); + CHECK_FALSE( + moshi_executor::guard::guard_temporal_fused_projection_layout_supported{}( + runtime_ev, ctx)); + CHECK_FALSE( + moshi_executor::guard:: + guard_depformer_fused_projection_layout_supported{}(runtime_ev, ctx)); for (int32_t layer = 0; layer < lm.depformer_num_layers; ++layer) { auto &unused = ctx.session.contract.lm.depformer_layers[static_cast(layer)] @@ -858,6 +883,19 @@ TEST_CASE( CHECK_FALSE( moshi_executor::guard::guard_depformer_projection_layout_unsupported{}( runtime_ev, ctx)); + + lm.depformer_weight_schedule_count = 1u; + CHECK_FALSE(moshi_executor::guard::guard_bound_root_operands_supported{}( + runtime_ev, ctx)); + CHECK(moshi_executor::guard::guard_depformer_projection_layout_unsupported{}( + runtime_ev, ctx)); + + lm.depformer_weight_schedule_count = static_cast(lm.dep_q); + lm.depformer_weight_schedule[0] = lm.dep_q; + CHECK_FALSE(moshi_executor::guard::guard_bound_root_operands_supported{}( + runtime_ev, ctx)); + CHECK(moshi_executor::guard::guard_depformer_projection_layout_unsupported{}( + runtime_ev, ctx)); } TEST_CASE("speech_moshi_predictor_rejects_tokenizer_capture_outside_ready") { @@ -1116,6 +1154,23 @@ TEST_CASE("speech_moshi_executor_rejects_missing_capacity") { CHECK(err == emel::error::cast(moshi_executor::error::bind_failed)); } +TEST_CASE("speech_moshi_executor_rejects_undersized_hidden_capacity") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + emel::kernel::sm kernel{}; + auto dependencies = make_executor_dependencies(kernel); + dependencies.capacity.hidden_dim = + static_cast(fixture.model->moshi_lm.dim - 1); + moshi_executor::sm executor{dependencies}; + emel::error::type err = emel::error::cast(moshi_executor::error::none); + moshi_executor::event::initialize init{*fixture.model}; + init.error_out = &err; + CHECK_FALSE(executor.process_event(init)); + CHECK(err == emel::error::cast(moshi_executor::error::bind_failed)); +} + TEST_CASE("speech_moshi_executor_rejects_undersized_sampling_capacity") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); if (fixture.model == nullptr) { diff --git a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp index e4872fca..385a3874 100644 --- a/tests/speech/tokenizer/moshi/lifecycle_tests.cpp +++ b/tests/speech/tokenizer/moshi/lifecycle_tests.cpp @@ -354,6 +354,35 @@ TEST_CASE("speech Moshi tokenizer rejects invalid injected geometry") { CHECK(machine.is(sml::state)); } +TEST_CASE("speech Moshi tokenizer rejects invalid token bounds and sentinels") { + const auto rejected = [](const int32_t text_initial_token, + const int32_t token_zero, + const int32_t token_ungenerated) { + std::array delays = {0, 1, 2}; + std::array cache{}; + moshi::sm machine{moshi::dependencies{ + .delays = std::span{delays}, + .cache = std::span{cache}, + .codebooks = 3, + .generated_audio_codebooks = 2, + .delayed_audio_codebooks = 2, + .cache_rows = 4, + .maximum_delay = 2, + .initial_delay_frames = 0, + .text_initial_token = text_initial_token, + .audio_initial_token = 200, + .token_zero = token_zero, + .token_ungenerated = token_ungenerated, + }}; + int32_t err = error_code(moshi::error::none); + return !machine.process_event(moshi::event::initialize{.error_out = err}) || + err == error_code(moshi::error::invalid_configuration); + }; + CHECK(rejected(0, -1, -2)); + CHECK(rejected(100, 0, -2)); + CHECK(rejected(100, -1, 0)); +} + TEST_CASE("speech Moshi tokenizer dispatch remains allocation free") { standard_fixture state; REQUIRE(state.initialize()); From 2d7762680fc0fb13bf3b0207642d2d634fef67dd Mon Sep 17 00:00:00 2001 From: gabewillen Date: Sat, 11 Jul 2026 15:04:15 -0500 Subject: [PATCH 61/61] fix loader and Moshi validation overflow --- src/emel/gguf/loader/detail.hpp | 3 +- src/emel/speech/predictor/moshi/guards.hpp | 7 ++++ tests/gguf/loader/lifecycle_tests.cpp | 15 +++++++ .../predictor/moshi_lifecycle_tests.cpp | 42 +++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/emel/gguf/loader/detail.hpp b/src/emel/gguf/loader/detail.hpp index e8e58ed8..4ec9829c 100644 --- a/src/emel/gguf/loader/detail.hpp +++ b/src/emel/gguf/loader/detail.hpp @@ -151,7 +151,8 @@ inline emel::error::type compute_emel_packed_q4_k_x8_data_size( } const uint64_t block_count = dims[0] / k_block_cols; - const uint64_t group_count = (rows + k_group_rows - 1u) / k_group_rows; + const uint64_t group_count = + rows / k_group_rows + static_cast((rows % k_group_rows) != 0u); uint64_t groups_and_blocks = 0u; if (!multiply_u64(group_count, block_count, groups_and_blocks) || !multiply_u64(groups_and_blocks, k_group_block_bytes, data_size_out)) { diff --git a/src/emel/speech/predictor/moshi/guards.hpp b/src/emel/speech/predictor/moshi/guards.hpp index eb447862..5e05ced5 100644 --- a/src/emel/speech/predictor/moshi/guards.hpp +++ b/src/emel/speech/predictor/moshi/guards.hpp @@ -2,6 +2,7 @@ #include "emel/kernel/detail.hpp" #include "emel/memory/hybrid/errors.hpp" +#include "emel/memory/view.hpp" #include "emel/model/loader/errors.hpp" #include "emel/model/moshi/detail.hpp" #include "emel/speech/predictor/moshi/context.hpp" @@ -18,6 +19,9 @@ struct guard_bind_contract_valid { if (lm.delay_count > lm.delays.size()) { return false; } + if (lm.n_q < 0 || lm.n_q >= action::k_max_codebooks) { + return false; + } int32_t max_delay = 0; for (uint32_t index = 0; index < lm.delay_count; ++index) { if (lm.delays[index] < 0) { @@ -51,7 +55,10 @@ struct guard_bind_contract_valid { row_count <= action::k_max_delay_rows && inference_contract && lm.delay_count >= static_cast(codebook_count) && runtime_ev.request.max_sequences > 0 && + runtime_ev.request.max_sequences <= + emel::memory::view::MAX_SEQUENCES && runtime_ev.request.max_blocks > 0 && + runtime_ev.request.max_blocks <= emel::memory::view::MAX_BLOCKS && runtime_ev.request.block_tokens > 0 && reserved_token_capacity > 0 && reserved_token_capacity <= static_cast(lm.context) && runtime_ev.request.sequence_id >= 0 && diff --git a/tests/gguf/loader/lifecycle_tests.cpp b/tests/gguf/loader/lifecycle_tests.cpp index 38769d29..ee4279af 100644 --- a/tests/gguf/loader/lifecycle_tests.cpp +++ b/tests/gguf/loader/lifecycle_tests.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -639,3 +640,17 @@ TEST_CASE("gguf loader explicit error guard classification") { parse_ctx.err = 0x7fff; CHECK(emel::gguf::loader::guard::parse_error_unknown{}(parse_runtime, ctx)); } + +TEST_CASE("gguf packed q4_k row group ceiling does not overflow") { + const std::array dims{ + 256u, + std::numeric_limits::max(), + 1u, + 1u, + }; + uint64_t data_size = 0u; + + CHECK(emel::gguf::loader::detail::compute_emel_packed_q4_k_x8_data_size( + dims, 2u, data_size) == + emel::error::cast(emel::gguf::loader::error::capacity)); +} diff --git a/tests/speech/predictor/moshi_lifecycle_tests.cpp b/tests/speech/predictor/moshi_lifecycle_tests.cpp index 67c90999..c93ce6cf 100644 --- a/tests/speech/predictor/moshi_lifecycle_tests.cpp +++ b/tests/speech/predictor/moshi_lifecycle_tests.cpp @@ -831,6 +831,48 @@ TEST_CASE("speech_moshi_predictor_rejects_memory_geometry_beyond_temporal_kv") { CHECK_FALSE(graph.initialized); } +TEST_CASE("speech_moshi_predictor_rejects_memory_actor_capacity_before_graph") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + emel::memory::hybrid::sm memory{}; + recording_graph_executor graph{}; + moshi::sm predictor{make_predictor_dependencies(graph, memory)}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*fixture.model}; + configure_predictor_initialize(init); + init.max_sequences = emel::memory::view::MAX_SEQUENCES + 1; + init.error_out = &err; + CHECK_FALSE(predictor.process_event(init)); + CHECK(err == emel::error::cast(moshi::error::bind_failed)); + CHECK_FALSE(graph.initialized); +} + +TEST_CASE( + "speech_moshi_predictor_bounds_codebooks_before_delay_slot_addition") { + auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf"); + if (fixture.model == nullptr) { + return; + } + auto model = std::make_unique(*fixture.model); + model->moshi_lm.n_q = std::numeric_limits::max(); + emel::memory::hybrid::sm memory{}; + recording_graph_executor graph{}; + moshi::sm predictor{make_predictor_dependencies(graph, memory)}; + emel::error::type err = k_no_error; + moshi::event::initialize init{*model}; + init.max_sequences = 1; + init.max_blocks = 1; + init.block_tokens = 1; + init.codebook_capacity = 1; + init.delay_cache_row_capacity = 1; + init.error_out = &err; + CHECK_FALSE(predictor.process_event(init)); + CHECK(err == emel::error::cast(moshi::error::bind_failed)); + CHECK_FALSE(graph.initialized); +} + TEST_CASE( "speech_moshi_executor_init_honors_shared_depformer_weight_schedule") { auto fixture = load_fixture_or_skip("moshi-tiny-lm.gguf");