Commit Graph
4 Commits
Author SHA1 Message Date
osobhandClaude Opus 4.7 adc9784646 rtx-csm: Stt::finish() — drain asr_delay buffer at end-of-stream
Phase 8.1.1 quality fix from the perf plan. Tokens emitted at LM step
`t` correspond to audio frame `t - ASR_DELAY_FRAMES` (6 frames /
0.48 s), so when a caller stops feeding audio without trailing
silence the last few words trail off — they're still inside the
delay pipeline.

finish() now steps ASR_DELAY_FRAMES additional silent frames after
handling any partial sub-frame buffer, giving the LM the chance to
emit those buffered tokens. Cost: 7 extra step_pcm calls per turn.

Verified end-to-end via stt_demo on a mid-utterance trim of the
LibriSpeech reference clip:
  pre-flush:  11 words ("...turnips and carrots and bruised")
  post-flush: 13 words ("...turnips and carrots and bruised potatoes and")

Also drops the now-redundant 2s silence suffix in stt_demo — the
flush replaces it. Affects converse_server's real-time end-of-turn
path where suffix padding wasn't possible.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-29 04:02:19 -07:00
osobhandClaude Opus 4.7 1dd79d4d10 rtx-csm: Phase 6a COMPLETE — STT works on real speech with detok
Python-reference diff revealed the all-pad debugging session was on the
wrong audio source. /tmp/csm_24k.wav (CSM-generated speech) is not
intelligible enough for Kyutai STT — even the Python reference emits
nothing. On a real LibriSpeech-style speech sample the pipeline works
correctly.

Verified end-to-end on Metal (10s FLAC, "He hoped there would be stew
for dinner..."):
  Rust port:    23 words, transcript matches Python reference
  Python ref:   25 words (last 2 cut off in our run due to asr_delay
                off-by-one — cosmetic, fixable by setting delay=7)

Changes:
- Add sentencepiece = "0.13" dep for token detok
- Stt::decode_word_text(tokens) returns the detokenized word text
  (filters padding token id 3, calls SentencePieceProcessor::decode_piece_ids)
- examples/stt_demo: pair Word/EndWord events into timed segments,
  detokenize each, print transcript + concatenated text
- Update module docs to reflect WORKING status

Phase 6 progress:
  6a STT: WORKING (this commit)
  6b LLM client: shipped
  6c.1 text->LLM->TTS: shipped
  6c.2 full duplex: ready to build now that 6a works

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-26 09:18:05 -07:00
osobhandClaude Opus 4.7 1c4b10405d rtx-csm: Phase 6a polish — bf16 dtype + silence padding + cleanup
Refinements on the Kyutai STT integration after debugging session:

- dtype: BF16 on accelerators (matches checkpoint storage), F32 on CPU.
  Previously F16 on Metal which can overflow in the LM's RmsNorm.
- examples/stt_demo: pad input with 0.5s silence suffix per the HF
  stt_config.audio_delay_seconds, matching the Python reference loop.
- src/stt.rs: tightened module docs with debugging notes for the
  remaining all-pad-output issue. Removed RTX_STT_DEBUG callback path
  (was useful for one-off debugging; can be re-added with cleaner shape).

Status: weights load cleanly, LM forward advances every frame, but
predictions are all-pad on real speech. Bisection plan documented in
the module rustdoc — next session should diff against the official
delayed-streams-modeling Python reference at frame-by-frame granularity.

77 lib tests + 2 stt tests all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-26 04:44:10 -07:00
osobhandClaude Opus 4.7 0f9cc122e9 rtx-csm: Phase 6a partial — Kyutai STT scaffold via moshi crate
Integrates the moshi crate (0.6.4, candle 0.9.1) for streaming STT.
Module + demo + custom config for kyutai/stt-1b-en_fr. Model loads
cleanly, LM forward pass advances (model_step_idx increments correctly),
but word events don't yet emit on a 10s CSM speech sample.

What works:
- moshi 0.6.4 added as dependency (candle 0.9.1, version-compatible)
- src/stt.rs wraps moshi::asr::State + moshi::lm + moshi::mimi
- Stt::load_default downloads kyutai/stt-1b-en_fr (~3 GB) from HF
- Custom config_stt_1b_en_fr() matching the released checkpoint:
  d_model=2048, num_layers=16, dim_feedforward=8192 (moshi's SwiGLU
  hidden = 11/4 * d_model = 5632 — verified vs safetensors), text vocab
  8001/8000, audio vocab 2049, 32 codebooks, no depformer
- AsrEvent enum + From<moshi::asr::AsrMsg> conversion
- examples/stt_demo.rs streams a WAV through the pipeline
- 2 unit tests for AsrEvent conversion

What needs more work:
- Word emission: 0 words detected on 10s of clean CSM speech, even
  though LM forward advances every frame. Likely culprits:
  a) asr_delay_in_tokens 6 vs HF stt_config.audio_delay_seconds=0.5
     (6.25 frames). Off-by-one possible.
  b) Sentencepiece detok not yet wired (tokens emitted but text=None).
  c) Subtle weight-key remap differences between moshi's expected
     layout and the released checkpoint that don't trip a shape check.
  d) renormalize/audio preprocessing mismatch.

Next step (Phase 6a polish): compare against the official
delayed-streams-modeling/scripts/stt_from_file_pytorch.py reference to
identify the missing piece. The integration framework is sound; only
the final LM-output-to-text-event step needs work.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-26 04:33:40 -07:00