Skip to content

stream: avoid duplicate lines in file output#3866

Open
Kakueeen wants to merge 1 commit into
ggml-org:masterfrom
Kakueeen:fix/issue-1056-stream-file-duplicates
Open

stream: avoid duplicate lines in file output#3866
Kakueeen wants to merge 1 commit into
ggml-org:masterfrom
Kakueeen:fix/issue-1056-stream-file-duplicates

Conversation

@Kakueeen

@Kakueeen Kakueeen commented Jun 8, 2026

Copy link
Copy Markdown

Problem

The stream example writes to the output file (-f flag) on every iteration, producing duplicate/incomplete lines. This happens because stdout uses \r (carriage return) to overwrite the same line in-place, but the file output writes a new line every iteration. The result is a file filled with many intermediate transcriptions that are difficult to parse.

Reported in #1056 with multiple users requesting a fix.

Observed

Running ./stream -f output.txt produces a file like:

Hello
Hello world
Hello world this is
Hello world this is a test
Hello world this is a test of
...

Instead of the expected clean output:

Hello world this is a test of streaming

Fix

  • Add -fnd / --file-no-dup flag (enabled by default) to only write finalized segments to file at n_new_line boundaries
  • Track n_segments_written to avoid re-writing segments from previous cycles
  • Add -fd / --file-dup flag to restore the old behavior for users who rely on it (e.g., real-time file monitoring in Vim)

The fix is 1 file, ~35 lines changed (mostly the new write-at-boundary logic).

Fixes #1056

Add -fnd/--file-no-dup option (enabled by default) to only write
finalized segments to file at n_new_line boundaries, avoiding the
duplicate lines that occur when writing on every iteration.

Fixes ggml-org#1056

Signed-off-by: Liu Zhangjian <liuzhangjian@uniontech.com>
@Kakueeen Kakueeen marked this pull request as ready for review June 8, 2026 09:25
@ailakshya

Copy link
Copy Markdown

Strong +1 — I hit exactly this building a Wayland dictation tool on top of stream, and the -f duplicate/partial lines make the file unusable for the most common downstream case: feeding the transcript to an LLM or a text-injector (what @zachrattner and @svyatoclav describe).

The proposed -fnd / --file-no-dup (write only finalized segments at n_new_line boundaries, default on, -fd to restore the current Vim-friendly behavior) is the right shape. Two refinements from experience, because a naive per-iteration line filter still leaks duplicates:

1. Key the "finalized" write off committed segments, not lines. In sliding mode (--step N>0), stream re-transcribes an overlapping window each iteration, and whisper frequently revises wording as more context arrives — I regularly saw the same utterance written twice with small variation ("it has…""it have…") across cycles. So "write lines added since the last newline" can still emit a slightly-different duplicate of text that was effectively already committed. Tracking n_segments_written against the committed/kept prefix (the text promoted via --keep / the n_new_line commit that becomes the next prompt) is more robust than a per-iteration line count: a segment is written once, only after it scrolls into the stable prefix.

2. Cover VAD mode (--step 0) too. It has the same file-duplication symptom via a different path — it re-runs inference over the accumulated buffer on each VAD trigger, so the whole utterance (not just partials) can land in the file multiple times. If --file-no-dup is scoped to the sliding path only, --step 0 users still get duplicates in -f. Ideally the flag gates both paths.

Backwards-compat via -fd is the right call for the tail -f / Vim workflow @ggerganov mentioned.

Happy to test a patch against the dictation/parse use-case (sliding and VAD, CPU and Vulkan) — I have repros for both duplication paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming to file leads to "duplicates"

2 participants