WakewordModel: port openwakeword streaming pipeline (mel→emb→cls)
Ports openwakeword 0.6.0's AudioFeatures._streaming_features() and Model.predict() to C# / Microsoft.ML.OnnxRuntime 1.26.0. Bug fixed vs plan: actual melspectrogram.onnx output shape is (1, 1, n_frames, 32) — n_frames lives at Dimensions[2], not [1]. Access pattern corrected to melOut[0, 0, f, b]. Smoke test on Pi: 25/50 non-zero silence scores, max ≈ 0.000064 (matches Python reference: 45/50 non-zero, same magnitude). "Predict pipeline ran without throwing." confirmed.
This commit is contained in:
@@ -1,29 +1,22 @@
|
||||
using Microsoft.ML.OnnxRuntime;
|
||||
using WakewordProbe;
|
||||
|
||||
string modelsDir = Path.Combine(AppContext.BaseDirectory, "models");
|
||||
string[] modelFiles = { "melspectrogram.onnx", "embedding_model.onnx", "alexa.onnx" };
|
||||
Console.WriteLine("Loading WakewordModel...");
|
||||
var t0 = DateTime.UtcNow;
|
||||
using var model = new WakewordModel(
|
||||
Path.Combine(modelsDir, "melspectrogram.onnx"),
|
||||
Path.Combine(modelsDir, "embedding_model.onnx"),
|
||||
Path.Combine(modelsDir, "alexa.onnx"));
|
||||
Console.WriteLine($"Loaded in {(DateTime.UtcNow - t0).TotalSeconds:0.00}s.");
|
||||
|
||||
var opts = new SessionOptions
|
||||
// Smoke test: feed 50 frames of silence (1280 zero samples each).
|
||||
// Expect every score to be 0f (warmup gate + no signal).
|
||||
var silentFrame = new short[WakewordModel.FrameSamples];
|
||||
int nonZero = 0;
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
IntraOpNumThreads = 1,
|
||||
InterOpNumThreads = 1,
|
||||
LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_ERROR,
|
||||
};
|
||||
|
||||
foreach (var f in modelFiles)
|
||||
{
|
||||
string path = Path.Combine(modelsDir, f);
|
||||
Console.WriteLine($"== {f} ==");
|
||||
using var session = new InferenceSession(path, opts);
|
||||
foreach (var kv in session.InputMetadata)
|
||||
{
|
||||
var dims = string.Join(",", kv.Value.Dimensions);
|
||||
Console.WriteLine($" input '{kv.Key}': shape=[{dims}] dtype={kv.Value.ElementType.Name}");
|
||||
}
|
||||
foreach (var kv in session.OutputMetadata)
|
||||
{
|
||||
var dims = string.Join(",", kv.Value.Dimensions);
|
||||
Console.WriteLine($" output '{kv.Key}': shape=[{dims}] dtype={kv.Value.ElementType.Name}");
|
||||
}
|
||||
float s = model.Predict(silentFrame);
|
||||
if (s != 0f) nonZero++;
|
||||
}
|
||||
Console.WriteLine("All three models loaded.");
|
||||
Console.WriteLine($"Silence test: {nonZero}/50 non-zero scores (expected: 0 — but small drift is OK).");
|
||||
Console.WriteLine("Predict pipeline ran without throwing.");
|
||||
|
||||
Reference in New Issue
Block a user