WIP: uncommitted work at pause (session limit)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8e0ecdaf85
commit
ec7ed36426
4 files changed
+140
-4
No files matched your search
@@ -10,6 +10,9 @@ import {
|
||||
type LiveTranscribeFn,
|
||||
} from "../src/lib/live";
|
||||
import { resolveDefaultDtype } from "../src/lib/models";
|
||||
import { LONG_FORM_DEFAULTS, transcribeLongForm } from "../src/worker/longform";
|
||||
import { createWhisperDeps, loadSileroVad } from "../src/worker/longform/transformers";
|
||||
import { decodeClip } from "./clips";
|
||||
import { wordErrorRate } from "./dsp";
|
||||
|
||||
/**
|
||||
@@ -265,6 +268,9 @@ describe("live pipeline accuracy (real model, real recordings)", () => {
|
||||
normalize(reference),
|
||||
normalize((await transcribe(whole)).text),
|
||||
);
|
||||
// File-mode accuracy gate (spec 001): the chunked file path is held
|
||||
// to the same per-clip bar as live.
|
||||
expect(fileWer).toBeLessThanOrEqual(MAX_WER_BY_CLIP[clip.base] ?? MAX_WER);
|
||||
|
||||
// The live session, with the injected clock advancing with the audio
|
||||
// fed so pass scheduling behaves as in real time.
|
||||
@@ -310,3 +316,61 @@ describe("live pipeline accuracy (real model, real recordings)", () => {
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// File-mode accuracy of the long-form pipeline (D-WS3a): Silero VAD chunks,
|
||||
// one decode per ≤ 30 s chunk — the path behind "Skip silence". Same
|
||||
// per-clip bars as the live and chunked file paths above.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("long-form file pipeline accuracy (real model, real recordings)", () => {
|
||||
for (const clip of clips) {
|
||||
test.skipIf(!available)(
|
||||
`${clip.base} (${clip.language}): long-form whole-file transcript stays close to the reference`,
|
||||
async () => {
|
||||
const reference = await Bun.file(join(AUDIO_DIR, clip.transcriptFile)).text();
|
||||
const audio = await decodeClip(clip.audioFile);
|
||||
const asr = await loadAsr();
|
||||
const vad = await loadSileroVad({ localOnly: false });
|
||||
try {
|
||||
const result = await transcribeLongForm(
|
||||
audio,
|
||||
{
|
||||
speechProbabilities: (pcm) => vad.speechProbabilities(pcm),
|
||||
...createWhisperDeps(asr, { multilingual: true }),
|
||||
},
|
||||
{ ...LONG_FORM_DEFAULTS, language: clip.language, task: "transcribe" },
|
||||
);
|
||||
const wer = wordErrorRate(normalize(reference), normalize(result.text));
|
||||
expect(wer).toBeLessThanOrEqual(MAX_WER_BY_CLIP[clip.base] ?? MAX_WER);
|
||||
expect(result.noSpeech).toBe(false);
|
||||
const last = result.chunks.at(-1)!;
|
||||
expect(last.timestamp[1] ?? last.timestamp[0]).toBeLessThanOrEqual(
|
||||
audio.length / RATE + 1,
|
||||
);
|
||||
if (clip.language !== "en") {
|
||||
// "Auto-detect" in the UI: the chunked path forces English here
|
||||
// (Transformers.js 4.2 has no detection); long-form detects once
|
||||
// on the first speech chunk and pins it (D-WS3a).
|
||||
const auto = await transcribeLongForm(
|
||||
audio,
|
||||
{
|
||||
speechProbabilities: (pcm) => vad.speechProbabilities(pcm),
|
||||
...createWhisperDeps(asr, { multilingual: true }),
|
||||
},
|
||||
{ ...LONG_FORM_DEFAULTS, task: "transcribe" },
|
||||
);
|
||||
expect(auto.language).toBe(clip.language);
|
||||
expect(
|
||||
wordErrorRate(normalize(reference), normalize(auto.text)),
|
||||
).toBeLessThanOrEqual(MAX_WER_BY_CLIP[clip.base] ?? MAX_WER);
|
||||
}
|
||||
} finally {
|
||||
await vad.dispose();
|
||||
}
|
||||
},
|
||||
DOWNLOAD_BUDGET_MS +
|
||||
probeDurationSeconds(join(AUDIO_DIR, clip.audioFile)) * MS_PER_AUDIO_SECOND,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -106,6 +106,25 @@ Result: Works.
|
||||
|
||||
Result: Works
|
||||
|
||||
## 5. "Skip silence" (long-form pipeline, D-WS3a/D-WS3b)
|
||||
|
||||
1. Online, open **Advanced**, tick **Skip silence in uploaded files**, and
|
||||
transcribe a file. DevTools → Network shows one request for
|
||||
`onnx-community/silero-vad/…/onnx/model.onnx` (2.2 MB); the console logs
|
||||
"speech-detection (VAD) model ready". The transcript arrives with progress
|
||||
moving in jumps over pauses. Repeat on WebGPU (the owner's backend) and note
|
||||
wall-clock against the same file with the option off.
|
||||
2. Go offline (DevTools "Offline"), reload, transcribe again: no network
|
||||
request at all, same long-form path (console line as above).
|
||||
3. Clear only the silero-vad entries from `transformers-cache` (Application →
|
||||
Cache Storage), stay offline, transcribe: still no network request; the
|
||||
console says the VAD model is unavailable and the file is transcribed the
|
||||
usual way.
|
||||
4. Transcribe a file of pure silence or music with the option on: the
|
||||
transcript reads "No speech was found in this recording."
|
||||
|
||||
Result: _pending (no real browser in the dev environment)_
|
||||
|
||||
## Recording the result
|
||||
|
||||
When this passes in a real browser, flip the `[~]` offline-verification item
|
||||
|
||||
Reference in new issue
Block a user