从“会说话的鱼”到数字人:多模态内容生成实战指南
2026/9/2 6:49:55 网站建设 项目流程

前段时间捣鼓了一个挺有意思的练手项目,名字叫“会说话的鱼啊”。项目目标非常简单:没有任何真人出镜,只给一张鱼的图片,就能自动生成一段“这条鱼在开口说话”的短视频。鱼的台词、语气、嘴部动作、画面节奏全部由程序自动完成。这件事听起来像是一个小玩具,但真正做下来,它覆盖了多模态内容生成的完整闭环:文本生成、语音合成、图像驱动、视频合成。把这套流程跑通之后,再去做数字人、品牌 IP 内容、短视频自动化生产,很多思路都能直接复用。

本文将围绕“会说话的鱼啊”这个项目,从多模态内容生成的核心概念讲起,接下来拆解整体架构与方案选型、环境准备、完整实战代码、进阶玩法、常见问题排错以及工程化最佳实践。内容偏实战,适合对 AIGC 应用开发感兴趣的同学,也适合想做音视频自动化内容生产的开发者。

1. 多模态内容生成:项目背后的核心概念

1.1 什么是多模态内容生成

“模态”(Modality)可以理解为信息的表达形式。文本、图片、音频、视频、三维模型,每一种都是独立的模态。传统 AI 任务大多是单模态的,比如文本分类只处理文字,图像识别只处理图片。而多模态内容生成,强调让 AI 同时理解多种模态的信息,再自动生成一种或多种新的模态内容。

举个例子,你给模型输入一张鱼的图片,模型识别出画面内容,结合提示词生成一段“鱼的自白”文本,这属于“图片理解 + 文本生成”。再往后,这段文本被合成为语音,语音又被用来驱动鱼图的嘴部动作,生成说话视频,这就变成了“跨模态的二次生成”。整个链路里,输入和输出都不再局限于单一媒介,所以叫多模态内容生成。

常见的技术形态包括文生图(Stable Diffusion、Midjourney)、文生视频(各类端到端视频生成模型)、图生视频、音频驱动数字人、语音克隆等。在这些能力之上,开发者可以把多个模型组合成一条生产线,变成一个具体的产品功能。“会说话的鱼啊”正是这种组合式应用的典型代表。

1.2 “会说话的鱼啊”到底生成了什么

这个项目的输入和输出线非常清晰:

  • 输入:一张鱼的图片 + 一个主题或角色设定。
  • 中间过程:LLM 自动生成台词文本,TTS 把台词合成为语音。
  • 输出:音频与图片结合,通过嘴型驱动模型生成“鱼在开口说话”的 MP4 视频。

用一张图来表示,就是“图片 + 文本 + 音频 → 视频”。这四个模态之间发生了两次关键转换:第一次是“文本 → 音频”,第二次是“图片 + 音频 → 视频”。前者是语音合成,后者是音画驱动。理解了这两次转换,你就掌握了整个项目的核心。

这里有一个容易被忽略的细节:传统视频技术里,画面和声音是靠剪辑软件拼接在一起的;而在多模态生成项目里,“音画对应关系”是由模型自动学习出来的。模型会分析音频中的节奏、音高和音素,让图片中的嘴部区域产生对应张合,从而实现听起来和看起来“对得上”的效果。

1.3 常见应用场景

这种能力不只是用来做一条会说话的鱼,稍微调整一下素材和封装,就能切入很多真实业务场景:

  • 数字人播报:把一张主播形象照变为播报视频,适用于新闻、电商、本地生活内容。
  • 品牌 IP 内容:企业吉祥物开口介绍产品,降低真人出镜成本。
  • 在线教育:让历史人物、动物、卡通角色“讲课”,增加课件趣味性。
  • 短视频批量生产:一套脚本批量生成多条不同形象的讲解视频,提升内容产出效率。
  • 社交媒体互动:用户上传图片,系统自动让图片“开口说话”,形成裂变传播。

多模态内容生成的价值不在于某个模型多酷,而在于它能替代大量重复的音视频制作工作。你可以把整个流程理解成一条“内容自动化流水线”,流水线上的每个环节都能被 AI 模型接管。

2. 整体架构与技术选型

2.1 四段式生成管线

在写代码之前,先把架构拆清楚。“会说话的鱼啊”整体是一条四段式管线:

  1. 文本生成:根据角色设定生成口语化台词。
  2. 语音合成:把台词转为自然语音。
  3. 嘴型驱动:让图片中的鱼根据音频“开口”。
  4. 视频后处理:合成字幕、音乐,输出最终视频。

每一段都可以独立替换。比如你今天用 GPT 系的模型生成文本,明天想换成国产开源模型,只需要改第一个环节的接口;今天用 SadTalker,明天想换成 Wav2Lip,只需要改第三个环节的调用。这种解耦设计非常重要,因为多模态生成领域迭代太快,把模块拆开才能快速升级。

2.2 技术选型对比

下面整理了我常用的方案对比,你可以根据自己的环境和需求选择:

模块可选方案特点推荐场景
文本生成GPT 系列、DeepSeek、Qwen、本地开源模型文案质量高,但需要 API 或本地资源入门可用任意国产或开源 API
语音合成edge-tts、ChatTTS、CosyVoice、GPT-SoVITSedge-tts 零门槛;ChatTTS 更自然;CosyVoice 支持高质量音色新手先用 edge-tts 跑通
嘴型驱动SadTalker、Wav2Lip、EchoMimic、DINetSadTalker 适合单图生成视频;Wav2Lip 适合给已有视频换嘴型单图说话首选 SadTalker
视频后处理ffmpeg、MoviePy做音频转换、字幕、拼接必备环节,建议学会 ffmpeg

这里特别说明一点:Wav2Lip 虽然名字里有“Lip”,但它的设计目标是给视频替换嘴型,需要你本来就有一段视频素材。而“会说话的鱼啊”只有一张静态图片,所以更适合使用 SadTalker。SadTalker 可以从单张图片和一段音频中,生成带有头部运动、表情变化和嘴部张合的视频,和我们的项目需求高度匹配。

2.3 为什么要做模块化选型

多模态内容生成最忌讳“想一口吃成胖子”。如果你一开始就希望用某个端到端大模型,直接输入图片和文案就输出完美视频,很可能会被成本、时间、部署门槛卡住。反过来,把流程拆成四个独立模块后,每个模块都可以单独测试、单独调优,出问题也容易定位。这也是我推荐“管线组合”而不是“一步到位”的原因。

3. 环境准备与版本说明

3.1 硬件与系统要求

本项目可以拆成两段来准备环境:

  • 文本生成和语音合成:这部分很轻量,普通电脑即可,语音合成使用在线 API 时几乎不消耗显卡资源。
  • 嘴型驱动:SadTalker 这类模型最好有 NVIDIA 显卡,并配置 CUDA 环境。没有 GPU 也能跑,但推理速度会明显变慢,适合先验证流程。

操作系统方面,Windows 10/11、Ubuntu 20.04/22.04 都可以。下面的命令以 Linux 环境为主,Windows 用户可以把bash命令换成对应工具或使用 WSL。

本文不会写死具体版本号,因为多模态开源项目更新非常频繁。示例环境为 Python 3.10 + PyTorch 2.x + CUDA 11.8,你实际使用时需要按照模型仓库的要求安装依赖,重点是保持 PyTorch 和 CUDA 版本匹配。

3.2 需要安装的基础工具

在开始之前,先确认以下工具是否已经安装:

  • Python 3.10 或更高版本。
  • ffmpeg,用于音视频转换和合成。
  • Git,用于拉取开源模型仓库。

以 Ubuntu 为例,安装基础工具的命令如下:

sudo apt update sudo apt install -y python3 python3-pip ffmpeg git python3 --version ffmpeg -version

Windows 用户建议直接安装 Python 官方安装包,并到 ffmpeg 官网下载可执行文件,把ffmpeg.exe所在目录加入系统 PATH。安装完成后,在命令行输入ffmpeg -version,如果能输出版本信息,说明环境正常。

3.3 项目目录结构

为了后续扩展,建议先创建清晰的目录结构:

fish-voice/ ├── input/ │ └── fish.png ├── output/ │ ├── script.txt │ ├── audio.mp3 │ └── result.mp4 ├── scripts/ │ ├── 01_generate_text.py │ ├── 02_generate_audio.py │ └── 03_run_sadtalker.sh └── models/ └── sadtalker/
  • input 存放鱼的图片素材。
  • output 存放每一步生成的中间产物。
  • scripts 存放文本生成、语音合成、嘴型驱动脚本。
  • models 存放开源模型仓库。

这样做有一个直接好处:每一步生成结果都有明确的落盘位置,排错时非常方便。后面我们生成的中间文件,都会按这个结构存放。

4. 完整实战:让鱼开口说话

4.1 准备鱼的图片素材

图片素材是整个项目成功与否的第一道门槛。如果你直接用一张普通的风景照,或者画面里有好几条鱼,视觉上很难让观众觉得“这条鱼在说话”。我建议先准备一张卡通风格的“拟人化鱼”图片,脸上结构可以夸张一些,嘴巴位置清楚一些。

如果不方便手绘,可以用文生图工具生成。提示词可以这样写:

一张可爱的卡通金鱼头像特写,正脸,嘴巴微张,清晰的大眼睛,干净背景, 暖色调,表情拟人化,适合动画短视频。

生成后,把图片放到input/fish.png。这里有一个实践技巧:图片中主体尽量居中,背景不要太复杂。SadTalker 需要检测面部关键点,鱼类和人类的五官结构有差异,如果模型检测不到关键点,就会报错或生成效果很差。为了让流程更容易跑通,你可以先使用“半人半鱼”的拟人化卡通形象,之后再逐步尝试写实鱼类素材。

4.2 编写角色设定并用大模型生成台词

准备好图片后,第一步是让大模型生成台词。为了让台词更像“一条鱼说出来的话”,我会给它一个详细角色设定。

下面是文本生成脚本的示例,路径为scripts/01_generate_text.py

# 文件路径:scripts/01_generate_text.py from openai import OpenAI # 请替换成你自己的模型服务地址和 API Key client = OpenAI( api_key="your-api-key", base_url="https://your-model-provider.example.com/v1" ) character = "金鱼小橙" style = "幽默、活泼、口语化,像短视频博主一样有节奏感" topic = "向大家介绍自己,并分享一个小时候差点被猫吃掉的故事" prompt = f""" 你是一位短视频编剧。请为角色“{character}”写一段约30秒的口播文案, 要求: 1. 风格:{style} 2. 内容:{topic} 3. 每一句不要太长,适合后期配音 4. 结尾加一句互动口号 """ response = client.chat.completions.create( model="qwen-plus", # 请替换为你实际使用的模型名 messages=[ {"role": "system", "content": "你是一名经验丰富的短视频文案策划。"}, {"role": "user", "content": prompt} ], temperature=0.85 ) script = response.choices[0].message.content print(script) with open("output/script.txt", "w", encoding="utf-8") as f: f.write(script)

这段代码做的事情很简单:调用大模型 API,传入角色设定和主题,拿到台词后写入output/script.txt。不同模型服务的接口可能略有差异,但整体思路是一致的。如果你使用的是非 OpenAI 兼容接口,只需要把请求格式改成对应 SDK 的写法。

跑通后,output/script.txt的内容大概是下面这样:

大家好,我是金鱼小橙!没错,就是那条在水族馆里游得最优雅的鱼。 今天我要讲一个秘密,我小时候差点被猫大仙吃掉…… 要不是我装死装得像,你们现在就见不到我了。 喜欢我的话,记得双击点赞,鱼生第一次求关注!

这套写法的好处是,角色设定和主题分离。你换一个角色、换一个主题,不需要改代码,只要改 prompt 里那两行字符串。如果后续要批量生成,可以把角色和主题做成配置文件,让脚本循环读取。

4.3 把台词变成语音

文本生成完毕后,进入语音合成环节。这里我推荐 edge-tts,因为它安装简单、无需 GPU、中文语音自然度不错,适合先把整条流程跑通。

安装 edge-tts:

pip install edge-tts

然后编写语音合成脚本,路径为scripts/02_generate_audio.py

# 文件路径:scripts/02_generate_audio.py import asyncio import edge_tts TEXT_PATH = "output/script.txt" OUTPUT_PATH = "output/audio.mp3" VOICE = "zh-CN-XiaoxiaoNeural" # 可按需求更换中文音色 RATE = "+8%" # 语速微调,让口播更轻快 async def main(): with open(TEXT_PATH, encoding="utf-8") as f: text = f.read().strip() communicate = edge_tts.Communicate(text, VOICE, rate=RATE) await communicate.save(OUTPUT_PATH) print(f"语音已保存到 {OUTPUT_PATH}") asyncio.run(main())

运行:

python scripts/02_generate_audio.py

这里需要注意,edge-tts 生成的是 MP3 格式。后面 SadTalker 对音频格式有要求,通常更推荐 WAV 格式,所以我们需要用 ffmpeg 转换一次,顺便统一采样率:

ffmpeg -i output/audio.mp3 -ar 16000 -ac 1 output/audio.wav

-ar 16000把采样率设为 16kHz,-ac 1转为单声道。这样转换后的音频更稳定,能减少嘴型驱动阶段的音画不同步问题。跑完这一步,output目录下应该同时有audio.mp3audio.wav

4.4 用 SadTalker 驱动图片说话

语音合成完成后,就进入了整个项目最核心的环节:图片 + 音频 → 视频。

首先克隆 SadTalker 官方仓库并安装依赖:

cd models git clone https://github.com/OpenTalker/SadTalker.git cd SadTalker pip install -r requirements.txt

如果你没有 GPU,可以跳过自动安装的部分,但推理速度会比较慢。建议参考官方 README 配置环境。模型权重文件一般需要从官方提供的下载链接手动下载,放到checkpoints目录下。模型权重较大,下载时请留意官方最新地址。

接下来执行推理。以下命令是参考官方仓库的常见用法,具体参数以你克隆到的版本 README 为准:

# 文件路径:scripts/03_run_sadtalker.sh cd models/SadTalker python inference.py \ --driven_audio ../../output/audio.wav \ --source_image ../../input/fish.png \ --result_dir ../../output \ --still \ --preprocess crop \ --enhancer gfpgan

参数说明如下:

  • --driven_audio:指定驱动视频的音频文件。
  • --source_image:指定刚才准备好的鱼图片。
  • --result_dir:输出目录。
  • --still:减少头部大幅运动,更符合鱼类静态画面的特点。
  • --preprocess crop:自动裁剪图片中的人脸区域,提升生成稳定性。
  • --enhancer gfpgan:对生成结果做画质增强,需要额外下载 GFPGAN 权重。

执行完成后,output目录下会出现一个生成的视频文件,通常是一个*.mp4文件。如果这一步能正常输出视频,说明整条链路已经打通了。对于第一次尝试来说,这一步最可能遇到的问题包括:模型权重缺失、CUDA 版本不匹配、图片面部检测失败。这些问题我会在第 6 章统一列出排查方式。

4.5 用 ffmpeg 做最终合成

SadTalker 输出的视频可能没有字幕,也没有背景音乐。为了让最终效果更像一条短视频,建议再用 ffmpeg 做一次合成。

首先给视频加上白底黑字字幕条,可以手动生成一个 SRT 字幕文件:

1 00:00:00,000 --> 00:00:03,500 大家好,我是金鱼小橙! 2 00:00:03,500 --> 00:00:06,800 没错,就是那条游得最优雅的鱼。

然后把字幕烧录到视频中:

ffmpeg -i output/result.mp4 -vf "subtitles=output/subtitle.srt" \ -c:a copy output/result_with_sub.mp4

如果想加一段背景音乐,可以准备一个轻快的 BGM 文件,与生成的音频混音:

ffmpeg -i output/result_with_sub.mp4 -i input/bgm.mp3 \ -filter_complex "[1:a]volume=0.15[bgm];[0:a][bgm]amix=inputs=2:duration=first[a]" \ -map 0:v -map "[a]" -c:v copy output/final.mp4

这条命令把背景音乐音量降到 15%,然后和语音混在一起,最终保留原视频画面。背景音乐不建议太大声,否则会盖过鱼的说话声。

4.6 运行与验证

把整个流程串起来以后,完整操作顺序是:

# 1. 生成台词 python scripts/01_generate_text.py # 2. 生成语音 python scripts/02_generate_audio.py # 3. 转换音频格式 ffmpeg -i output/audio.mp3 -ar 16000 -ac 1 output/audio.wav # 4. 嘴型驱动生成视频 bash scripts/03_run_sadtalker.sh # 5. 加字幕 ffmpeg -i output/result.mp4 -vf "subtitles=output/subtitle.srt" -c:a copy output/result_with_sub.mp4 # 6. 加背景音乐 ffmpeg -i output/result_with_sub.mp4 -i input/bgm.mp3 \ -filter_complex "[1:a]volume=0.15[bgm];[0:a][bgm]amix=inputs=2:duration=first[a]" \ -map 0:v -map "[a]" -c:v copy output/final.mp4

预期输出是一段几秒钟到十几秒钟的短视频,画面中的鱼随语音节奏出现嘴部张合动作。第一次跑通时不要追求高画质,先确认“鱼嘴在动、声音对得上、画面不崩”这三个基本点。

5. 让鱼的世界更丰富:进阶玩法

5.1 多角色对话

一条鱼开口说话还不够过瘾,你可以做两条鱼对话的小剧场。做法是分别准备两张鱼的图片,各自生成一段对话音频,再分别跑一次 SadTalker,最后用 ffmpeg 把两段视频横向拼接在一起:

ffmpeg -i output/fish_a.mp4 -i output/fish_b.mp4 \ -filter_complex "hstack=inputs=2" output/fish_dialog.mp4

如果要让对话节奏自然,可以为两条鱼设置不同的音色,比如一条用活泼女声,一条用低沉男声。edge-tts 中切换voice参数即可实现。

5.2 情绪化语音与画面变化

多模态内容生成的进阶方向是“情绪同步”。当前 SadTalker 能根据音频节奏驱动嘴部,但对情绪的捕捉仍然有限。如果你想做出更细腻的效果,可以在文本生成阶段加入情绪标注,比如在台词前标记“(开心)”“(叹气)”,让 TTS 使用不同的语速和音调。更进一步,可以根据不同段落切换鱼的背景色或镜头缩放,让视频更有层次感。

5.3 端到端视频生成模型的取舍

随着多模态生成大模型快速发展,现在很多端到端模型可以直接用一张图和一段文案生成视频,不再需要传统管线。这类模型在画面一致性、自然度上往往更优,但也存在三个现实问题:成本高、参数可控性弱、本地部署门槛高。因此在实际项目中,模块化管线仍然很有价值。你可以把大模型生成的片段作为素材,再用传统管线做精细控制;也可以等端到端模型更成熟后,把对应模块整体替换。

6. 常见问题与排查思路

6.1 常见问题表格

下面是我在跑这类项目时遇到的典型问题,整理成表格方便你快速对照:

问题现象常见原因解决思路
生成视频时提示检测不到人脸图片面部结构不清晰或主体过小换正脸清晰图片,减少复杂背景,使用 crop 预处理
显卡 CUDA 报错或显存不足PyTorch/CUDA 版本不匹配,分辨率过高按官方要求重装 PyTorch,降低生成分辨率或开启半精度
嘴部动作和语音明显不对齐音频采样率不一致,音频时长过长统一转为 16kHz 单声道 WAV,分段生成再拼接
模型权重下载慢或失败权重来自外部托管平台,网络不稳定手动下载权重并放到 checkpoints 目录,或使用镜像
edge-tts 请求失败音色名称错误或服务不可用检查 voice 参数,确认网络能访问对应服务
生成结果面部扭曲输入图片角度偏斜或光照不均重新生成正脸素材,尝试关闭 enhancement 或换预处理方式
ffmpeg 找不到字幕文件相对路径写错使用绝对路径,并确认 SRT 文件存在

6.2 一套实用的排查顺序

如果整条流程某个环节出了问题,不要盲目试参数,我建议按下面的顺序排查:

  1. 确认每一步的输出文件是否生成。比如audio.wav存在吗?SadTalker 是否真的读取到了这个文件?
  2. 查看日志或终端输出的最后几行错误信息。多模态项目报错通常都会提示具体是哪一行代码出了问题。
  3. 检查模型权重是否完整。权重下载中断会导致加载时报 OSError。
  4. 检查依赖版本。PyTorch、CUDA、Python 版本是常见故障源,尤其是 GPU 环境。
  5. 先用最短的一句话音频测试。如果最短音频能通过,再逐步加长,这样能快速定位是音频问题还是模型问题。

只要能把问题定位到“某一个模块”,解决起来就简单很多。这也是我一直强调模块化管线的原因:四段流程里,每一段都有独立的输入输出,排错就像查流水线一样清晰。

7. 最佳实践与工程建议

7.1 让生成过程可重复

多模态生成天然带有随机性,如果跑第二次结果不一样,并不一定是代码问题。为了让结果可复现,建议做好三件事:

  • 固定随机种子:在文本生成和模型推理代码中设置seed
  • 保留中间产物:每次生成的文本、音频、视频都存起来,不要覆盖。
  • 记录参数配置:把模型版本、TTS 音色、语速、SadTalker 参数写进一个配置文件。

推荐用 YAML 配置管理这些参数:

# config.yaml llm: provider: openai-compatible model: qwen-plus temperature: 0.85 tts: voice: zh-CN-XiaoxiaoNeural rate: "+8%" sadtalker: preprocess: crop enhancer: gfpgan still: true

脚本运行时读取配置,这样你想调整任何参数,都不需要改代码,只改配置文件就够了。

7.2 安全与合作边界

多模态内容生成的版权问题必须重视。这里给出几条底线建议:

  • 使用自己创作、购买或明确标注可商用的图片素材。
  • 生成语音时,不要使用真人声音的克隆技术制作欺骗性内容。
  • 涉及人物肖像时,必须获得授权;不要用本项目技术合成虚假发言。
  • 批量生成内容时,注意遵守平台内容规范和法律法规。

如果项目要部署到生产环境,建议在后台增加内容审核环节,对生成的文本和视频做二次检查,避免出现违规内容。

7.3 性能与成本优化

如果你的目标是在服务器上批量生成视频,性能和成本会很快变成瓶颈。可以优先从这几个方向优化:

  • 采用异步任务队列,避免同步阻塞大量请求。
  • SadTalker 推理使用 GPU 时开启半精度,降低显存占用。
  • 对 4K 图片先做压缩,处理完再恢复画质,提升推理速度。
  • 文本生成和语音合成尽量使用并发调用,缩短单条视频的总耗时。
  • 实现缓存机制:相同台词、相同音色的音频可以直接复用,避免重复调用 TTS。

这里分享一个项目经验:如果一次要生成 100 条视频,不要写一个 for 循环从头跑到尾,而是把预处理、生成、后处理拆成三个任务队列。预处理失败的直接跳过,不浪费 GPU 时间;后处理出错的单独重跑,不影响整批任务。

7.4 日志与监控

在工程化落地时,日志是排查问题的核心手段。每个模块的开始和结束都要打印日志,至少包含:

  • 模块名称。
  • 输入文件路径和大小。
  • 输出文件路径。
  • 耗时。
  • 成功或失败状态。

可以用 Python 的logging模块记录这些信息,线上环境再接入日志平台。有了日志,用户反馈“某条视频生成失败”时,你才能快速定位是哪个模块出了问题。

8. 总结与学习路线

“会说话的鱼啊”这个项目看起来简单,实际上是一条非常完整的多模态内容生成链路。你不仅学会了调用 LLM 生成文本、使用 TTS 合成语音,还动手跑通了单图驱动视频的模型,理解了图片、文本、音频、视频四种模态之间如何互相转换。

如果接下来想继续深入,我建议按这样的路线走:

  1. 先把本文的流程用同一张图片、不同音频完整跑通,感受参数对结果的影响。
  2. 尝试用不同的 TTS 方案替换 edge-tts,对比自然度。
  3. 尝试替换嘴型驱动模型,比如从 SadTalker 切到 Wav2Lip,理解两种模型的适用边界。
  4. 引入多角色对话和批量生成,设计一个简单的内容生产脚本。
  5. 研究端到端多模态大模型的发展,定期把新能力纳入你的工具箱。

遇到报错不要急着放弃。这类项目的主要难点不在代码量,而在环境依赖、模型权重和参数调试上。每一次踩坑,都是对生成链路更深的理解。建议从今天开始,用一张你喜欢的图片,跑通第一段 3 秒视频,你会看到整条链路并没有想象中那么难。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询