fix(cli): map ggml model stem to whisper.cpp dotted DTW preset (fixes large-v3) (#2086)

`hyperframes transcribe --model large-v3` aborted with "unknown DTW preset
'large-v3'". whisper.cpp's --dtw flag wants a dotted alignment-heads preset
(large.v3), but we passed the hyphenated ggml file stem (large-v3). They
coincide for tiny/base/small/medium(+.en) — why it slipped through — but
diverge for the large-v* family. Map stem -> preset (- to .) so large-v1/v2/v3
(and large-v3-turbo) work; no-op for the others. Also fixes media-use, which
shells to `hyperframes transcribe`.


Claude-Session: https://claude.ai/code/session_01H5k87mPZ4d6yiFwcWSb8Vv

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Miguel Ángel
2026-07-08 19:53:26 -04:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 20b9034577
commit 8e04d01969
2 changed files with 40 additions and 1 deletions
@@ -0,0 +1,24 @@
import { describe, expect, test } from "vitest";
import { dtwPresetForModel } from "./transcribe.js";
describe("dtwPresetForModel", () => {
// The large family is the regression: model files are hyphenated but
// whisper.cpp's --dtw preset is dotted, so `--dtw large-v3` used to abort
// with "unknown DTW preset 'large-v3'".
test.each([
["large-v3", "large.v3"],
["large-v2", "large.v2"],
["large-v1", "large.v1"],
["large-v3-turbo", "large.v3.turbo"],
])("maps hyphenated large model %s to dotted preset %s", (model, preset) => {
expect(dtwPresetForModel(model)).toBe(preset);
});
// tiny/base/small/medium (+.en) already match their preset — must be unchanged.
test.each(["tiny", "base.en", "small.en", "medium.en", "small"])(
"leaves preset-identical model %s unchanged",
(model) => {
expect(dtwPresetForModel(model)).toBe(model);
},
);
});
+16 -1
View File
@@ -205,6 +205,21 @@ function prepareAudio(audioPath: string): string {
return wavPath;
}
/**
* Map a ggml model file-stem to whisper.cpp's `--dtw` alignment-heads preset.
*
* The two mostly coincide, so the stem was long passed straight to `--dtw` — but
* they diverge for the large family: the model files are hyphenated
* (`ggml-large-v3.bin`) while the DTW presets are dotted (`large.v3`,
* `large.v3.turbo`). `--dtw large-v3` makes whisper-cli abort with
* "unknown DTW preset 'large-v3'", surfacing as "Transcription failed". The
* tiny/base/small/medium (+`.en`) families have no hyphen, so `-`→`.` is a no-op
* for them and correct for the large family.
*/
export function dtwPresetForModel(model: string): string {
return model.replace(/-/g, ".");
}
/**
* Transcribe an audio or video file and save transcript.json to the output directory.
*/
@@ -281,7 +296,7 @@ export async function transcribe(
"--output-file",
outputBase,
"--dtw",
effectiveModel,
dtwPresetForModel(effectiveModel),
"--suppress-nst",
];
if (detectedLanguage) {