Python Websocket调用Spleeter产生残留进程引发内存问题求助
残留进程产生原因
- 你在每次请求处理逻辑中都会新建
Spleeter的Separator实例,该实例底层依赖TensorFlow运行时,默认会根据CPU核心数创建多个工作进程用于加速推理计算,任务执行完成后你没有显式释放实例和相关资源,TensorFlow持有的进程不会自动销毁,就会残留,你截图中的进程就是TensorFlow生成的推理工作进程。 - 音频分离属于CPU密集型任务,你直接将其放在asyncio协程中同步执行,会阻塞整个Websocket服务的事件循环,导致进程资源回收逻辑被卡住,进一步加剧残留问题。
- 你当前调用的
separator.join()仅会等待任务执行完成,不会主动销毁底层启动的工作进程。
优化方案
1. 全局复用Separator实例
不要每次请求都新建Separator,初始化成本极高且每次新建都会生成新的进程池。可以在服务启动时根据需要支持的stem类型提前初始化对应实例,全局复用,同时提前配置TensorFlow线程数限制进程生成数量:
# 服务启动时全局初始化,不要放在split函数里 import tensorflow as tf # 限制TensorFlow并行线程数,避免生成过多进程 tf.config.threading.set_intra_op_parallelism_threads(2) tf.config.threading.set_inter_op_parallelism_threads(2) # 示例:如果只用到2stems和5stems,可以提前初始化对应实例 separator_map = { "2": Separator('spleeter:2stems'), "5": Separator('spleeter:5stems') }
2. 显式释放资源
如果业务需要每次新建Separator实例,任务完成后要主动清理TensorFlow会话和实例:
# 分离任务完成后执行 tf.keras.backend.clear_session() del separator # 手动触发垃圾回收 import gc gc.collect()
3. 异步调度CPU密集型任务
不要在协程中同步跑分离任务,用线程池调度避免阻塞事件循环:
# 把separate_to_file的调用放到线程池里跑 loop = asyncio.get_running_loop() if audioFormat == "mp3": await loop.run_in_executor(None, lambda: separator.separate_to_file(pathname, "/tmp/filename", codec="mp3", bitrate=bitRate) ) else: await loop.run_in_executor(None, lambda: separator.separate_to_file(pathname, "/tmp/filename") )
4. 补充临时资源清理逻辑
任务完成后主动删除生成的临时文件和目录,避免磁盘和资源占用:
# 发送完zip文件后执行 import shutil os.close(temp) os.remove(pathname) shutil.rmtree(p)
内容的提问来源于stack exchange,提问作者isic5
相关产品推荐
相关产品推荐

