FunASR icon indicating copy to clipboard operation
FunASR copied to clipboard

Onnxruntime, 持续 2pass 模式,循环解码大概4小时,线程会卡死

Open locasxe opened this issue 8 months ago • 18 comments

Notice: In order to resolve issues more efficiently, please raise issue following the template. (注意:为了更加高效率解决您遇到的问题,请按照模板提问,补充细节)

🐛 Bug

Onnxruntime, 持续 2pass 模式,循环解码大概4小时,线程会卡死

To Reproduce

onnxruntime c++ 最新版,持续解码大概4小时,会推理线程卡死,但是内存和cpu还是一直占着,通过 pstack 查看,是卡在 VAD 的 e2e_vad.h 里的 DetectOneFrame(FrameState cur_frm_state, int cur_frm_idx, bool is_final_frame)。

Expected behavior

应当持续正常解码。

Environment

  • OS Linux:
  • FunASR Version 最新:
  • ModelScope Version 最新:
  • PyTorch Version 2.6.0:
  • How you installed funasr pip:
  • Python version 3.10:

locasxe avatar May 14 '25 06:05 locasxe

问题查到可能是卡在这个函数的循环里,问下大佬,这个函数的作用,为什么里面要有这个if 判断,这样不会有可能出不来循环吗 void PopDataBufTillFrame(int frame_idx) { int frame_sample_length = int(vad_opts.frame_in_ms * vad_opts.sample_rate / 1000); while (data_buf_start_frame < frame_idx) { if (data_buf_size >= frame_sample_length) { data_buf_start_frame += 1; data_buf_size = data_buf_all_size - data_buf_start_frame * frame_sample_length; } } }

locasxe avatar May 15 '25 02:05 locasxe

你是使用docker镜像版本funasr-runtime-sdk-online-cpu-0.1.12 吗?我遇到处理时延随连接建立时长增加而增加的现象,也是2pass模型,越跑,时延越大。

EAGLE50 avatar May 22 '25 03:05 EAGLE50

你是使用docker镜像版本funasr-runtime-sdk-online-cpu-0.1.12 吗?我遇到处理时延随连接建立时长增加而增加的现象,也是2pass模型,越跑,时延越大。

这个感觉是不是并发不够啊,我这个已经找到原因了,确实是bug.

locasxe avatar May 22 '25 11:05 locasxe

@locasxe 是什么原因导致的?可否描述一下,谢谢

wujushan avatar May 23 '25 12:05 wujushan

@locasxe 是什么原因导致的?可否描述一下,谢谢

个人查到的是,Onnxruntime的e2e_vad.h 的reset函数好像搞错了,重置的时候,它又声明了一遍,导致根本没有重置,一直在累积,所以你一直解码,最后就溢出了。

locasxe avatar May 26 '25 09:05 locasxe

具体怎么修改一下,能否说一下?

liuwenchang avatar Jun 04 '25 01:06 liuwenchang

Image @locasxe 哥,是不是这个地方

liuwenchang avatar Jun 05 '25 02:06 liuwenchang

Image @locasxe 哥,是不是这个地方

不好意思刚看到,是的。

locasxe avatar Jun 05 '25 02:06 locasxe

测了了两天,把这个改了还是不行,还是有概率触发死循环

liuwenchang avatar Jun 09 '25 06:06 liuwenchang

测了了两天,把这个改了还是不行,还是有概率触发死循环

你需要内部置入例如每隔24h去输入is_final去reset(),不然一直跑也是会溢出的

locasxe avatar Jun 26 '25 02:06 locasxe

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

majic31 avatar Sep 01 '25 09:09 majic31

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

改一下源码也可以,int 溢出了,他有个总长度的int,一直发数据,长度在累加,超过大概18个小时,int就溢出了。改成long 可以无限一直发下去

liuwenchang avatar Sep 01 '25 09:09 liuwenchang

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

改一下源码也可以,int 溢出了,他有个总长度的int,一直发数据,长度在累加,超过大概18个小时,int就溢出了。改成long 可以无限一直发下去

如果是长音频,的确有你说的情况,感谢! 但是也的确发现内存有在微涨,我这边是8核8路并发,内存经过12小时后,现在大概在5.4G(6小时左右的时候是在4.9GB),这部分内存一直都不释放的(即使停止压测也不释放)

majic31 avatar Sep 02 '25 01:09 majic31

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

改一下源码也可以,int 溢出了,他有个总长度的int,一直发数据,长度在累加,超过大概18个小时,int就溢出了。改成long 可以无限一直发下去

不改int时,感觉会一直上涨,但将int改为long后,目前能看到内存回落了,比较神奇~ 很奇怪的就是data_buf_all_size难道不是当前session有效吗?(比较奇怪~)

majic31 avatar Sep 10 '25 12:09 majic31

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

改一下源码也可以,int 溢出了,他有个总长度的int,一直发数据,长度在累加,超过大概18个小时,int就溢出了。改成long 可以无限一直发下去

不改int时,感觉会一直上涨,但将int改为long后,目前能看到内存回落了,比较神奇~ 很奇怪的就是data_buf_all_size难道不是当前session有效吗?(比较奇怪~)

这个内存问题很大一部分是因为你音频发送的速度过快,那个存储任务的vector队列会一直扩大,当你任务消耗完了,vector也不会往自动变小,好像是asio 那个框架问题。长度改成long应该是解决不了内存不断增加的问题。你试试循环不间断发音频,中间不要sleep,内存会一直扩。

liuwenchang avatar Sep 11 '25 02:09 liuwenchang

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

改一下源码也可以,int 溢出了,他有个总长度的int,一直发数据,长度在累加,超过大概18个小时,int就溢出了。改成long 可以无限一直发下去

不改int时,感觉会一直上涨,但将int改为long后,目前能看到内存回落了,比较神奇~ 很奇怪的就是data_buf_all_size难道不是当前session有效吗?(比较奇怪~)

这个内存问题很大一部分是因为你音频发送的速度过快,那个存储任务的vector队列会一直扩大,当你任务消耗完了,vector也不会往自动变小,好像是asio 那个框架问题。长度改成long应该是解决不了内存不断增加的问题。你试试循环不间断发音频,中间不要sleep,内存会一直扩。

我现在就是不间断发送wav二进制chunk,每个chunk之间sleep 1ms,的确发现会不断增长,但到一定量后,会适当释放一些内存(我是16核16GB内存,16路并发),目前仍在压测中。 请问下您说的存储任务具体是那一块?还是e2e-vad.h里面的那个data_buf吗?

majic31 avatar Sep 11 '25 02:09 majic31

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

改一下源码也可以,int 溢出了,他有个总长度的int,一直发数据,长度在累加,超过大概18个小时,int就溢出了。改成long 可以无限一直发下去

不改int时,感觉会一直上涨,但将int改为long后,目前能看到内存回落了,比较神奇~ 很奇怪的就是data_buf_all_size难道不是当前session有效吗?(比较奇怪~)

这个内存问题很大一部分是因为你音频发送的速度过快,那个存储任务的vector队列会一直扩大,当你任务消耗完了,vector也不会往自动变小,好像是asio 那个框架问题。长度改成long应该是解决不了内存不断增加的问题。你试试循环不间断发音频,中间不要sleep,内存会一直扩。

我现在就是不间断发送wav二进制chunk,每个chunk之间sleep 1ms,的确发现会不断增长,但到一定量后,会适当释放一些内存(我是16核16GB内存,16路并发),目前仍在压测中。 请问下您说的存储任务具体是那一块?还是e2e-vad.h里面的那个data_buf吗?

不是这里,是websocket-server-2pass.cpp 里,800ms一个chunk,如果cpu处理不过来,会不断放到排队的队列里。生产者消费者,如果传音频过快,来不及消费,就会不断累积,任务在排队。strand_->post 任务这块会累积很大内存

liuwenchang avatar Sep 11 '25 02:09 liuwenchang

每个会话结束了,会发送is_final=True,应该就不会触发这个问题了吧~

改一下源码也可以,int 溢出了,他有个总长度的int,一直发数据,长度在累加,超过大概18个小时,int就溢出了。改成long 可以无限一直发下去

不改int时,感觉会一直上涨,但将int改为long后,目前能看到内存回落了,比较神奇~ 很奇怪的就是data_buf_all_size难道不是当前session有效吗?(比较奇怪~)

这个内存问题很大一部分是因为你音频发送的速度过快,那个存储任务的vector队列会一直扩大,当你任务消耗完了,vector也不会往自动变小,好像是asio 那个框架问题。长度改成long应该是解决不了内存不断增加的问题。你试试循环不间断发音频,中间不要sleep,内存会一直扩。

我现在就是不间断发送wav二进制chunk,每个chunk之间sleep 1ms,的确发现会不断增长,但到一定量后,会适当释放一些内存(我是16核16GB内存,16路并发),目前仍在压测中。 请问下您说的存储任务具体是那一块?还是e2e-vad.h里面的那个data_buf吗?

不是这里,是websocket-server-2pass.cpp 里,800ms一个chunk,如果cpu处理不过来,会不断放到排队的队列里。生产者消费者,如果传音频过快,来不及消费,就会不断累积,任务在排队。strand_->post 任务这块会累积很大内存

收到,感谢指点🤝。我看了下,这块的确是个内存积压点,但的确有个问题,一旦我停止发送了,貌似也不会清理内存(这里不像离线转写那边,那边内存控制的很好,非常稳定),而是一定要到一个条件(具体还不清楚)才会释放掉部分空间~ 我再研究下,多交流,非常感谢!

majic31 avatar Sep 11 '25 03:09 majic31