Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

识别结果中文字重复,这大概会是那个环节出问题了? #70

Open
charlesw1234 opened this issue Aug 31, 2023 · 8 comments

Comments

@charlesw1234
Copy link

为了学习 FastASR 我自己用 C 语言重写了一遍,输出如下:

$ tests/test-kaldi2.exe ~/ai.data/asr/20230825-0733.wav 
Log at: tests/test-kaldi2-15122.jsons
Using: libsndfile-1.0.31
/home/wangli/ai.data/asr/20230825-0733.wav:
	Sample Rate: 16000
	Channels: 1
	Sections: 1
	Frames: 59051
	Load frames: 59051
	Model Init: True
	Model Forward: True
result: "<blk><blk>好好好好好好好好好好好好好好好好好好学学学学学学学学学学学学学学学学学学习习习习习习习习习习习天天天天天天天天天天天天天向向向向向向向向向向向上上上上上上上上上上上上上上上上上上上上"

需要的话我可以上传到这里或者 gitee,其他的地方都对了,只有文字似乎重复了。我在 wav 里面说的是:“好好学习天天向上”,用 FastASR 的 examples 可以正常识别。

谢谢。

@chenkui164
Copy link
Owner

在 Tensor.h 有个方法是dump(), 将需要观察的数据导出到tmp.bin文件。然后用matlab或者python,比对两个版本之间的差异。这个只能逐一排查,并没有好的办法。

@csukuangfj
Copy link

ab或者python,比对两个版本之间的差异。这个只能逐一排查,并没有好的办法。

这个是 transducer 还是 ctc?

@chenkui164
Copy link
Owner

ab或者python,比对两个版本之间的差异。这个只能逐一排查,并没有好的办法。

这个是 transducer 还是 ctc?

是transducer的,decode method直接用的gready search。

@charlesw1234
Copy link
Author

我明白了,多谢指点。稍晚点我开个 git,把我代码发出来供大家解剖玩耍。

@charlesw1234
Copy link
Author

提交到这里了: https://github.com/charlesw1234/fastc-asr

问题我还没来得及改。只要把 k2_rnnt2_cli 的 wenet_params.bin 放到 models/k2_rnnt2_cli/ 目录里,然后再运行:
tests/test-kaldi2.exe tests/hhxx.ttxs.wav 就可以看到结果了。

我是用一个叫 scons 的编译工具来编译的,在 ubuntu 里面,只要: apt-get install scons 就行了。运行 scons 就可以完成编译。

读取 wav,我用了 libsndfile,所以在 ubuntu 里面要:apt-get install libssl-dev libsndfile1-dev libfftw3-single libfftw3-dev libopenblas-dev。

有兴趣的话先玩着。

@chenkui164
Copy link
Owner

chenkui164 commented Sep 3, 2023

问题找到了,find_max函数没有对max_at初始化。

void findmax(value_t *din, size_t len, value_t *max_value, size_t *max_at)
{
assert(len > 0);
*max_value = din[0];
*max_at = 0;
for (size_t index = 1; index < len; ++index)
if (din[index] > *max_value) {
*max_value = din[index];
*max_at = index;
}
}

@charlesw1234 ,看代码风格,应该是某位潜水的大佬,C语言的goto我只在linux内核里见人用过。函数命名规范,解构清晰,实在是佩服!

@charlesw1234
Copy link
Author

好多天没上来看了,一个是公司事情忙,一个是懒(主要是这原因 :) )。我是两个没想到,一个是没想到 @chenkui164 会帮忙找出 bug......,所以我今天上午花了两个小时把问题找出来了,正是你说的..... *max_at = 0 忘记了。这是我的第二个没想到,竟然阴沟翻船了。 :p 早知道你就帮忙找出来我就偷懒了,哈哈。

调试过程中我发现一个有趣的现象:

#include <stdio.h>
#include <stdlib.h>
#include <fftw3.h>

#define FFT_SIZE 512
#define STEP     4
int main(void) {                                                                          
    //float fft_input[FFT_SIZE];
    //fftwf_complex fft_output[FFT_SIZE];
    float *fft_input = (float*)malloc(sizeof(float) * FFT_SIZE);
    fftwf_complex *fft_output = (fftwf_complex *)malloc(sizeof(fftwf_complex) * FFT_SIZE);
    fftwf_plan plan;
    plan = fftwf_plan_dft_r2c_1d(FFT_SIZE, fft_input, fft_output, FFTW_ESTIMATE);
    for (size_t at = 0; at < FFT_SIZE; ++at) fft_input[at] = (float)at;
    fftwf_execute(plan);
    for (size_t at = 0; at < FFT_SIZE; at += STEP) {
        printf("%3zu: ", at);
        for (size_t offset = 0; offset < STEP; ++offset)
            printf("(%8.3f, %8.3f) ", fft_output[at + offset][0],
                   fft_output[at + offset][1]);
        printf("\n");
    }
    fftwf_destroy_plan(plan);
    free(fft_output);
    free(fft_input);
    return 0;
}

如果是用注释掉的方式,也就是在栈里面分配 fft_input、fft_output,那么即便输入完全相同,fftwf_execute每次的输出也会不同。而如果用 malloc 在堆里面分配 fft_input、fft_output,那么只要输入相同,fftwf_execute 的输出总是相同,只是仍然跟栈里情况不同。但是无论用那种方式,都不影响最终结果。

@chenkui164
Copy link
Owner

chenkui164 commented Sep 7, 2023

对实数做fft,它的结果是共轭对称的,所以fftw只给出了前面0-256的结果,后面的数是随机的。可以参考官方的解释。http://www.fftw.org/doc/The-1d-Real_002ddata-DFT.html#The-1d-Real_002ddata-DFT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants