如何序列化ndarray列表?Celery任务传参遇JSON序列化错误
解决Celery传递numpy数组时的JSON序列化错误
问题原因
Celery默认采用JSON作为消息序列化器,但numpy.ndarray对象无法被JSON直接序列化——哪怕你把deque转成列表或元组,列表里的核心元素还是ndarray,因此会触发报错:Object of type ndarray is not JSON serializable。
可行解决方案
方案1:将numpy数组序列化为字节后传递
把每个ndarray转成字节流,同时携带数组的形状、数据类型信息,任务端再还原成原数组:
- 发送端代码:
import numpy as np # 序列化帧为字节,同时记录形状和数据类型 serialized_frames = [frame.tobytes() for frame in labeled_frame_dequeue] frame_shapes = [frame.shape for frame in labeled_frame_dequeue] frame_dtypes = [str(frame.dtype) for frame in labeled_frame_dequeue] # 调用Celery任务 generate_clip_from_frames.delay( labeled_video_path, serialized_frames, frame_shapes, frame_dtypes, video_width, video_height, fps )
- Celery任务端代码:
import numpy as np @app.task def generate_clip_from_frames(video_path, serialized_frames, frame_shapes, frame_dtypes, width, height, fps): # 还原ndarray数组 labeled_frame_dequeue = [ np.frombuffer(frame_bytes, dtype=dtype).reshape(shape) for frame_bytes, shape, dtype in zip(serialized_frames, frame_shapes, frame_dtypes) ] # 后续视频生成逻辑...
方案2:用临时文件存储帧数据
如果帧数据量较大,直接传递字节流会占用过多消息队列资源,建议将帧保存到本地临时文件,仅传递文件路径:
- 发送端代码:
import tempfile import numpy as np # 创建临时目录存储帧文件 with tempfile.TemporaryDirectory() as tmpdir: frame_paths = [] for idx, frame in enumerate(labeled_frame_dequeue): frame_path = f"{tmpdir}/frame_{idx}.npy" np.save(frame_path, frame) frame_paths.append(frame_path) # 调用任务,传递帧文件路径列表 generate_clip_from_frames.delay( labeled_video_path, frame_paths, video_width, video_height, fps )
- Celery任务端代码:
import numpy as np @app.task def generate_clip_from_frames(video_path, frame_paths, width, height, fps): # 读取帧文件还原ndarray labeled_frame_dequeue = [np.load(path) for path in frame_paths] # 后续视频生成逻辑... # 临时目录会自动被系统清理,无需手动删除文件
方案3:修改Celery序列化器为Pickle
直接让Celery使用Pickle序列化(注意:Pickle存在安全风险,仅在完全信任任务发送方的场景下使用):
- 修改Celery配置文件:
# celery.py或项目配置文件中 app = Celery('tasks') app.conf.update( task_serializer='pickle', accept_content=['pickle'], result_serializer='pickle', )
配置完成后,即可直接传递ndarray列表:
generate_clip_from_frames.delay(labeled_video_path, labeled_frame_dequeue, video_width, video_height, fps)
内容的提问来源于stack exchange,提问作者raj-kapil
相关产品推荐
相关产品推荐

