新增 Silero VAD 时间轴评分对比与可复现推理

This commit is contained in:
Xin Wang
2026-10-22 21:25:47 +08:00
parent 43724c13e4
commit c9b618e634
14 changed files with 379 additions and 14 deletions
+18 -1
View File
@@ -38,12 +38,13 @@ test("curve gaps are not connected and steps remain on the audio clock", () => {
test("recorded inference exports agree on audio identity and retain all 44 checkpoints", async () => {
const files = [
["maai", "maai-ch-kyoto"], ["smart_turn", "smart-turn-v3.2"],
["maai", "maai-ch-kyoto"], ["smart_turn", "smart-turn-v3.2"], ["silero_vad", "silero-vad"],
] as const;
const exports = await Promise.all(files.map(async ([model, directory]) => parseScoreExport(
JSON.parse(await readFile(new URL(`../../../experiments/${directory}/results/score-timeline.json`, import.meta.url), "utf8")), model)));
const identity = (data: typeof exports[number]) => data.calls.map(call => [call.call_id, call.audio_path, call.audio_sha256, call.duration_ms]);
assert.deepEqual(identity(exports[0]), identity(exports[1]));
assert.deepEqual(identity(exports[0]), identity(exports[2]));
for (const data of exports) {
assert.equal(data.calls.reduce((n, call) => n + call.checkpoints.length, 0), 44);
for (const call of data.calls) {
@@ -52,3 +53,19 @@ test("recorded inference exports agree on audio identity and retain all 44 check
}
}
});
test("Silero checkpoints use only the last available frame, and speech is inverted once", async () => {
const data = parseScoreExport(JSON.parse(await readFile(new URL(
"../../../experiments/silero-vad/results/score-timeline.json", import.meta.url), "utf8")), "silero_vad");
assert.equal(data.sample_interval_ms, 32);
for (const call of data.calls) {
assert.equal(call.points[0][0], 32);
for (const [ms] of call.points) assert.equal(ms % 32, 0);
for (const [ms, score] of call.checkpoints) {
const frame = scoreAt(call.points, ms, 32);
assert.ok(frame);
assert.equal(frame[1], score);
assert.ok(frame[0] <= ms && ms - frame[0] < 32);
}
}
});