From 7429dbd787bb24fdff7a0dac5f48b59e4e3472b6 Mon Sep 17 00:00:00 2001 From: LauraGPT <18321252+LauraGPT@users.noreply.github.com> Date: Fri, 28 Aug 2026 17:14:09 +0000 Subject: [PATCH] fix(runtime): trace SenseVoice backend stages Signed-off-by: LauraGPT <18321252+LauraGPT@users.noreply.github.com> --- .../funasr-sensevoice/funasr-sensevoice.cpp | 27 +++++++++++++- runtime/llama.cpp/tests/test_backend_flags.py | 36 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/runtime/llama.cpp/sensevoice/funasr-sensevoice/funasr-sensevoice.cpp b/runtime/llama.cpp/sensevoice/funasr-sensevoice/funasr-sensevoice.cpp index bad235053..533d59947 100644 --- a/runtime/llama.cpp/sensevoice/funasr-sensevoice/funasr-sensevoice.cpp +++ b/runtime/llama.cpp/sensevoice/funasr-sensevoice/funasr-sensevoice.cpp @@ -11,6 +11,7 @@ #include "gguf.h" #include +#include #include #include #include @@ -21,6 +22,15 @@ static const float LN_EPS = 1e-5f; +static void trace_stage(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fputc('\n', stderr); + fflush(stderr); +} + // ---- audio loader: any wav/mp3/flac, any rate/channels -> 16k mono (miniaudio) ---- #define FUNASR_AUDIO_IMPLEMENTATION #include "funasr_audio.h" @@ -212,6 +222,7 @@ int main(int argc,char**argv){ graph_backend graph_be=make_graph_backend(backend_name); // load model + trace_stage("[sensevoice] loading model metadata"); model m; gguf_init_params gp={false,&m.ctx_w}; gguf_context*gg=gguf_init_from_file(gguf_path.c_str(),gp); if(!gg){fprintf(stderr,"load gguf failed\n");return 1;} auto rd=[&](const char*k,int d){int i=gguf_find_key(gg,k);return i<0?d:(int)gguf_get_val_u32(gg,i);}; @@ -222,6 +233,7 @@ int main(int argc,char**argv){ std::vector qtok(nq); for(int i=0;i vocab; {int ki=gguf_find_key(gg,"sv.vocab"); if(ki>=0){int nv=gguf_get_arr_n(gg,ki); vocab.resize(nv); for(int i=0;i lg((size_t)V*N); ggml_backend_tensor_get(logits,lg.data(),0,ggml_nbytes(logits)); std::vector seg_ids; int prev=-1; // greedy CTC: argmax per frame -> collapse -> drop blank for(int n=0;n wav; if(!funasr_load_audio_16k_mono(wav_path.c_str(),wav)){fprintf(stderr,"read audio failed\n");return 1;} + trace_stage("[sensevoice] audio ready: %zu samples",wav.size()); std::vector> segs; + trace_stage("[sensevoice] running VAD"); if(!funasr_vad_segments(vad_path,wav,vad_maxseg,segs)){fprintf(stderr,"vad failed\n");return 1;} + trace_stage("[sensevoice] VAD ready: %zu segments",segs.size()); for(auto&s:segs){ int off=(int)((int64_t)s.first*16000/1000), end=(int)((int64_t)s.second*16000/1000); if(end>(int)wav.size())end=wav.size(); if(end-off seg(wav.begin()+off,wav.begin()+end); int t=0; auto fb=compute_fbank(seg,t); @@ -280,7 +303,9 @@ int main(int argc,char**argv){ } else { int32_t T=0,Fc=F; std::vector fb; int end_ms=0; if(!wav_path.empty()){ + trace_stage("[sensevoice] loading audio"); std::vector wav; if(!funasr_load_audio_16k_mono(wav_path.c_str(),wav)){fprintf(stderr,"read audio failed\n");return 1;} + trace_stage("[sensevoice] audio ready: %zu samples",wav.size()); end_ms=(int)((int64_t)wav.size()*1000/16000); int t=0; fb=compute_fbank(wav,t); T=t; } else { diff --git a/runtime/llama.cpp/tests/test_backend_flags.py b/runtime/llama.cpp/tests/test_backend_flags.py index a83f6f768..c5052cc8b 100644 --- a/runtime/llama.cpp/tests/test_backend_flags.py +++ b/runtime/llama.cpp/tests/test_backend_flags.py @@ -74,3 +74,39 @@ def test_sensevoice_flushes_device_initialization_boundaries_to_stderr(): assert "initializing %s backend on %s (%s)" in initializer assert "initialized %s backend on %s; resolving buffer type" in initializer assert "fflush(stderr);" in initializer + + +def test_sensevoice_traces_post_backend_pipeline_boundaries(): + source = SENSEVOICE.read_text(encoding="utf-8") + + boundaries = [ + "loading model metadata", + "model ready", + "loading audio", + "audio ready", + "running VAD", + "VAD ready", + "building graph", + "graph built", + "allocating graph", + "graph allocated", + "compute starting", + "compute complete", + ] + for boundary in boundaries: + assert boundary in source + + assert "static void trace_stage(" in source + trace_stage = source.split("static void trace_stage(", maxsplit=1)[1].split("}", maxsplit=1)[0] + assert "vfprintf(stderr" in trace_stage + assert "fflush(stderr);" in trace_stage + + for before, after in ( + ("loading model metadata", "model ready"), + ("loading audio", "audio ready"), + ("running VAD", "VAD ready"), + ("building graph", "graph built"), + ("allocating graph", "graph allocated"), + ("compute starting", "compute complete"), + ): + assert source.index(before) < source.index(after)