Why can a long transcript miss the ending?

If your team has a transcript but cannot find the final sentence, do not begin by increasing a batch parameter. Trace the recording, the selected speech regions and the returned result first. A nonempty response does not prove complete coverage.

Consider an interview whose last remark is audible in the original file but absent from the transcript. That observation alone does not identify a model defect: establish whether the loaded audio includes the end, whether segmentation retains it and whether the client saves the full response.

The example below is one offline SenseVoice configuration with an external speech detector, not a fix for every missing tail. Silence, segmentation and inference or client failures need different evidence.

Three places to look before changing parameters

  1. The input: listen to the end of the same decoded file, not another copy with a similar name.
  2. The boundary: inspect cuts near the missing sentence. Speech detection chooses regions; it does not verify the words.
  3. The result: distinguish an empty record, incomplete response and saved text. Retain errors rather than filling a missing sentence by guesswork.

Start with one explicit offline configuration

Use an already prepared, separate FunASR 1.4.15 environment with PyTorch, working audio-decoding dependencies and access to model weights. Follow the installation and environment guide for platform preparation, then check the Python SDK guide. The version check below inspects installed package metadata; it is not proof of a complete installation or acoustic inference.

Place a local file you are authorized to process at meeting.wav. Validate the environment with a short recording before moving to longer business recordings; initial loading may download models. The output contains transcript text, which should stay out of public logs. The recipe pins the toolkit version, not every dependency or model revision; record and pin those separately for deployment.

from importlib.metadata import version
from pathlib import Path

installed = version("funasr")
if installed != "1.4.15":
    raise RuntimeError(f"Expected FunASR 1.4.15, found {installed}")

audio = Path("meeting.wav")
if not audio.is_file():
    raise FileNotFoundError(audio)

from funasr import AutoModel

model = AutoModel(
    model="iic/SenseVoiceSmall",
    vad_model="fsmn-vad",
    vad_kwargs={"max_single_segment_time": 30000},
    device="cpu",
)
result = model.generate(
    input=str(audio),
    batch_size_s=300,
)
if not result or not isinstance(result[0], dict):
    raise RuntimeError("No result record; inspect audio and model logs")
text = result[0].get("text", "")
if not isinstance(text, str) or not text.strip():
    raise RuntimeError("Empty transcript; inspect audio, silence and VAD output")
print(text)

This explicit CPU path handles VAD regions individually; batch_size_s is not a CPU parallelism control or a speed recommendation. Empty output needs inspection: silence, VAD selection, input problems or inference errors are possible causes. It is not automatically success or a model defect. The example deliberately stops for inspection and supplies no fabricated transcript output.

Acceptance before admitting long recordings

  1. Verify inputs: check decodability, actual duration, channels and sample rate. A successful read or nonempty transcript is not completeness evidence.
  2. Cover business difficulties: include short recordings, long silences, overlapping speakers, sustained speech and a clear spoken tail. Listen around cuts, key entities and the end. A timestamp gap may also be silence.
  3. Record resources and latency: identify model/dependency versions, hardware, device, audio and concurrency. Separate initialization from file-call timing, state warmup conditions, measure peak RAM and GPU memory, and retain errors and empty results.
  4. Increase load gradually: raise duration and concurrency to establish admission, timeout, queue and retry policies. One successful request does not validate all durations; a client timeout does not prove that backend inference was cancelled.

See the meeting-transcript acceptance checklist and reproducible performance guide. The former's MOSS sentence_info audit script has a specific input contract, not an adapter for arbitrary SenseVoice results. Structural checks do not prove text accuracy or complete speech coverage.

Appendix: windows, resources and parameter units

The resource path inside a file call

This offline path loads the complete audio waveform into CPU memory, then organizes ASR inputs using VAD regions. It is not a bounded-memory stream that reads only the current segment from disk. Segmentation can change the work in one inference batch, but the full waveform, decoding buffers, segment metadata, outputs and concurrent requests still consume resources.

For a 16 kHz, mono, float32 waveform alone, one hour is about 230 MB. This is a data-size estimate, not measured peak process RAM or GPU memory, and excludes decoder copies and model state. It cannot establish support for every file or equal GPU memory for one-hour and one-minute inputs. Validate acceptable durations on the chosen hardware, model, audio format and concurrency.

See whole-file loading and segment sorting and the audio-decoding entry point. Source inspection explains the data path; it does not replace peak-memory measurement.

Two parameters with different boundaries

  • max_single_segment_time=30000: An FSMN-VAD endpoint threshold in milliseconds (ms), used in frame-level speech segmentation decisions. It is not a file-duration limit or a guarantee of exactly equal segments or cuts at word and sentence boundaries.
  • batch_size_s=300: A VAD-wrapper batch budget in seconds (s), converted to milliseconds internally. Grouping considers the longest segment duration multiplied by the number of segments. It is not simply the sum of segment durations or a hard memory cap; a longer segment may still be processed alone.

CPU exception: the current wrapper disables that grouping budget for device="cpu" and handles segments individually. Changing batch_size_s in this example is therefore not evidence of CPU batch-throughput optimization. A prepared and validated GPU setup needs new measurements, not inherited memory or speed conclusions. See budget units and the CPU branch and grouping rule.

Choose models and services separately

  • This is an offline SenseVoice example with explicitly configured external FSMN-VAD. Check Paraformer configuration and outputs separately. SenseVoice rich-text tags are not verified emotion accuracy.
  • Third-party MOSS-Transcribe-Diarize has its own whole-recording transcription and native diarization path. It does not require this external VAD or CAM++ recipe. Anonymous speaker labels are not verified real-world identities.
  • For realtime microphone transcription, select an explicitly supported streaming model and service using the deployment matrix. Smaller offline batches do not create a streaming protocol. See model selection for capability differences.

This article explains pinned source behavior, not new long-recording performance or accuracy measurements. The previous page's timing and full-coverage promotion lacked complete reproduction conditions and has been removed. Repository history preserves that text; it is not a current deployment promise.

Next, use the meeting-transcript checklist to choose what to listen for at the end of a representative recording. Its downloadable MOSS checker has a different input contract from this SenseVoice recipe.