Fun-ASR-Nano long recordings are truncated at the hard-coded 256-token generation budget
Problem
Long recordings transcribed with Fun-ASR-Nano are cut off after roughly a few minutes, while Whisper can transcribe the same kind of long recordings successfully.
Retrying the same saved WAV from Handy's History reproduces the failure, so this is not related to the model idle/unload timeout.
Reproduction
Environment:
- Handy 0.9.6
- macOS / Apple Silicon (M1 Pro)
- Model:
handy-computer/Fun-ASR-Nano-2512-gguf/Fun-ASR-Nano-2512-Q8_0.gguf - Metal GPU backend
- VAD enabled
Example:
- Record about 2m42s of continuous Mandarin speech
- Transcribe with Fun-ASR-Nano
- The latter part of the recording is missing / the transcription is incomplete
- Retry transcription from History using the exact same WAV
- It fails in the same way
The Handy log contains the direct cause:
[transcribe_cpp][WARN] funasr_nano run: output truncated at 256 tokens — decode reached the generation budget before end-of-stream; the transcript may be incomplete.Root cause
transcribe.cpp currently hard-codes Fun-ASR-Nano's per-run generation budget:
// Per-run generation budget.
constexpr int k_max_new = 256;Because Handy sends the long recording through this batch path as one transcription, a sufficiently long natural transcript can hit the 256-token output limit before EOS.
Whisper does not show the same problem because its long-form path processes audio in chunks/windows rather than requiring the whole recording to fit inside one autoregressive output budget.
Expected behavior
Handy should reliably transcribe long recordings with Fun-ASR-Nano without silently losing the latter part of the audio.
Suggested fix
I don't think simply increasing k_max_new from 256 to 512/1024 is a robust fix; that only moves the failure threshold.
A better long-form path would be one of:
- split long recordings into VAD / duration-bounded speech chunks, run Fun-ASR-Nano on each chunk, then concatenate results; or
- expose truncation/generation-budget information from
transcribe.cppand let Handy automatically chunk/retry whenOUTPUT_TRUNCATEDoccurs.
Ideally Handy should treat the truncation status as a correctness failure rather than returning an incomplete transcript as if it were complete.
Separate observation
With Handy language set to auto, the log currently shows:
Language intent 'auto' resolved to 'en' for model '...Fun-ASR-Nano...'
transcribe-cpp run: task=Transcribe, language=Some("en"), initial_prompt=falseThis does not cause the 256-token truncation, but it may also be worth checking for Chinese Fun-ASR usage.
Source: cjpais/Handy