【AI项目】从零构建 AI 视频生成系统:多模型编排、长时异步与链路降级工程实践

发布时间:2026/8/24 14:41:02
【AI项目】从零构建 AI 视频生成系统:多模型编排、长时异步与链路降级工程实践 ✨文末附开源仓库地址做 AI 应用落地的同学可以直接拉下来跑。本文为技术演示项目仅供学习和交流参考不建议直接用于生产环境。当 LLM 遇见文生图、图生视频、TTS如何把它们串成一个完整的产品前言最近在关注多模型编排的工程化落地发现很多团队在做 AI 产品时都会遇到类似的问题多个模型如何协同长时异步任务怎么处理某个环节失败怎么保证整体不崩因此抽时间做了一套可运行的 Demo把多模型链式调用、异步轮询、降级策略这些工程实践落地成代码。把开发过程中遇到的真实问题在 Demo 中复现并给出解决方案方便自己复盘总结也给有需要的同学参考。项目目标为餐饮行业打造一套智能视觉内容生成系统用户只需输入菜名系统自动生成菜品图片和宣传视频。技术挑战如何编排多个 AI 模型协同工作如何处理长时异步任务视频生成需要几十秒如何保证系统的健壮性某个环节失败不能全盘崩溃系统架构整体设计┌─────────────────────────────────────────────────────────────────┐ │ 前端 Vue 3 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │ │ 图片生成页 │ │ 视频编排页 │ │ 拖拽排序 (vuedraggable) │ │ │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 后端 FastAPI │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 任务编排引擎 │ │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────────┐ │ │ │ │ │ LLM │──▶│文生图│──▶│图生视频│──▶│ TTS │──▶│视频合并 │ │ │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 阿里云百炼 API │ │ Qwen-Plus wan2.6-t2i wan2.7-i2v qwen3-tts-flash │ └─────────────────────────────────────────────────────────────────┘核心流程整个系统的核心是一个多模型链式调用流程LLM 生成提示词用户输入菜名Qwen-Plus 自动生成 4 种不同风格的提示词文生图调用 wan2.6-t2i 生成菜品图片用户选择用户挑选满意的图片编排视频顺序LLM 生成口播文案根据菜名生成简短的宣传文案≤20字TTS 语音合成调用 qwen3-tts-flash 合成口播音频图生视频调用 wan2.7-i2v将音频作为 driving_audio 传入视频合并ffmpeg 拼接所有片段添加字幕使用演示Step 1输入菜名批量生成图片用户只需输入菜名每行一个系统自动调用 Qwen 大模型为每个菜名生成 4 种不同风格的提示词然后批量生成图片如图输入「宫爆鸡丁」和「尖椒鸡」两个菜名系统自动计算2 个菜品 × 4 种风格 8 张图片右侧实时展示生成结果。Step 2挑选图片跳转视频编排生成完成后用户勾选满意的图片点击右上角「去编排视频」按钮进入视频编排页面如图8 张图片全部生成完毕用户勾选了宫爆鸡丁和尖椒鸡各一张点击「去编排视频 (2)」即可进入下一步。Step 3编排顺序一键生成宣传视频在视频编排页面用户可以拖拽调整视频顺序、编辑口播文案点击生成后系统自动完成口播文案生成 → 语音合成 → 图生视频 → 视频合并最终输出一条带口播和字幕的完整宣传视频。技术选型思考为什么选 FastAPI原生异步视频生成是长时任务需要异步处理类型安全Pydantic 自动校验请求参数文档自动生成Swagger UI 方便前后端联调为什么前端用 Vue 3Composition API复杂状态管理更清晰生态成熟Element Plus 组件库开箱即用拖拽交互vuedraggable 实现视频编排排序为什么用阿里云百炼模型齐全LLM、文生图、图生视频、TTS 一站式配齐API 统一一个 SDK 调用所有模型降低集成成本国内访问无需翻墙延迟低核心代码实现1. 异步任务轮询视频生成是异步任务需要轮询查询状态def_poll_task_status(task_id:str,max_wait:int600)-dict:轮询任务状态最长等待 max_wait 秒waited0interval15# 每 15 秒查询一次whilewaitedmax_wait:responsedashscope.VideoSynthesis.async_fetch(task_idtask_id,api_keyDASHSCOPE_API_KEY)statusresponse.output.task_statusifstatusSUCCEEDED:returnresponse.outputelifstatusFAILED:raiseException(f任务失败:{response.output.message})time.sleep(interval)waitedintervalraiseTimeoutError(f任务超时:{task_id})2. 首尾帧控制为了让视频片段无缝衔接采用首尾帧模式defgenerate_video_from_first_last_frame(first_frame_path:str,last_frame_path:str,prompt:str,duration:int)-str: 首尾帧模式 - 第 1 帧 first_frame本段开始画面 - 最后 1 帧 last_frame上一段结束画面保证衔接 # 提取首帧 base64first_frame_b64encode_image(first_frame_path)# 提取尾帧 base64last_frame_b64encode_image(last_frame_path)payload{model:VIDEO_MODEL,input:{media:[{type:first_frame,url:first_frame_b64},{type:last_frame,url:last_frame_b64},],prompt:prompt,},parameters:{duration:duration}}# ... 调用 API3. 口播音频集成视频 API 支持传入驱动音频实现画面与语音同步defgenerate_video_with_audio(image_path:str,prompt:str,audio_url:str,# TTS 合成的音频 URLduration:int)-str:payload{model:VIDEO_MODEL,input:{media:[{type:image,url:image_b64},{type:driving_audio,url:audio_url},# 关键],prompt:prompt,},parameters:{duration:duration}}4. 降级策略某个环节失败时不能让整个流程崩溃# 口播生成失败视频照常生成无音频audio_urlifdish_name:try:tts_resultgenerate_voiceover_for_dish(dish_name,duration)audio_urltts_result[audio_url]exceptExceptionase:logger.warning(f口播生成失败视频将无音频:{e})# 首尾帧模式失败降级为首帧模式try:resultgenerate_video_from_first_last_frame(...)exceptExceptionase:logger.warning(f首尾帧模式失败降级为首帧:{e})resultgenerate_video_from_first_frame(...)踩坑记录1. 万相 API 响应格式问题response.output.image报错dict object has no attribute image原因新版 SDK 返回的是 dict不是对象解决# 错误image_urlresponse.output.image.url# 正确image_urlresponse.output[image][url]# 或兼容写法image_urlresponse.output.get(image,{}).get(url)2. ffmpeg drawtext 中文字幕问题Windows 上 ffmpeg drawtext 报错Fontconfig error: Cannot load default config file原因standalone ffmpeg 没有 fontconfig 配置解决显式指定字体路径并转义冒号# Windows 路径的冒号需要转义为 \:font_pathC\\:/Windows/Fonts/msyh.ttcdrawtextfdrawtexttext{text}:fontfile{font_path}:fontsize483. subprocess 错误信息丢失问题ffmpeg 执行失败但日志看不到具体错误原因capture_outputTrue捕获了 stderr但异常时没有打印解决try:resultsubprocess.run(cmd,checkTrue,capture_outputTrue,textTrue)exceptsubprocess.CalledProcessErrorase:logger.error(fffmpeg 失败:{e.stderr})# 显式记录 stderrraise工程化实践1. 配置管理# 支持 PyInstaller 打包后的路径def_get_data_path():ifgetattr(sys,frozen,False):returngetattr(sys,_MEIPASS,os.path.dirname(__file__))returnos.path.dirname(__file__)# API Key 从环境变量读取DASHSCOPE_API_KEYos.getenv(DASHSCOPE_API_KEY,)2. 日志系统# 同时输出到控制台和文件logging.basicConfig(levellogging.INFO,format%(asctime)s [%(name)s] %(levelname)s: %(message)s,handlers[logging.StreamHandler(),logging.FileHandler(logs/app.log,encodingutf-8)])3. 前端交互拖拽排序vuedraggable 实现视频片段编排实时进度轮询后端接口显示当前处理进度预览弹窗点击缩略图预览视频历史管理支持删除/清空生成的文件性能数据任务耗时说明LLM 生成提示词~3s4 种风格单张图片生成~10s含网络传输5秒视频生成~45s异步轮询口播文案生成~3sLLM 调用语音合成~2sTTS 调用视频合并(2段)~2s本地 ffmpeg完整流程2 个菜品的宣传视频含口播总耗时约 2 分钟。总结这个项目让我对 AI 应用落地有了更深的理解模型编排是核心单个模型能力有限串联起来才能解决复杂问题异步处理是必须视频生成动辄几十秒必须异步 轮询降级策略很重要生产环境不能因为某个环节失败就全盘崩溃工程化决定成败配置管理、日志、错误处理这些决定了系统能否真正上线如果你也在做 AI 应用开发希望这些经验对你有帮助。项目地址Gitee - primeDish-AI ⭐ 欢迎 Star本 Demo 仅做技术复盘与学习演示基于多模型编排工程实践经验提炼后续还会持续迭代补充更多场景优化。