先交代一下背景。我们是个3人小团队,主要做短视频代运营和内容种草,手头唯一的硬件资产是两台MacBook Pro和一台装了四块机械硬盘的旧工作站,没有任何独立显卡。去年年底我们突然接到一个需求:客户希望我们用AI给产品批量生成带货短视频,一个月保底二百条。当时我第一反应是这事可以先本地部署Stable Diffusion加视频生成模型试试,结果一查资料满屏都是“训练需要8卡A100”“显存不够微调不了”“本地部署至少24G显存起步”,差点直接劝退。
后来我们换了个思路:既然本地跑不动开源模型,那就干脆别跑,直接用官方API把这些重活外包出去。折腾了大概两个多月,一条从“客户一句话需求”到“成品视频自动交付”的AI视频流水线跑通了。这篇文章就是来记录我们当初的选型逻辑、架构设计、踩过的坑,以及这套零显卡方案真实的成本和时间数据。如果你也是小团队、预算有限、没有GPU资源,但想量产AI视频,这篇应该能帮你省掉不少弯路。
1. 三个穷鬼的AI视频梦:为什么最后选了API路线
最开始我们内部也争论过,要不要省吃俭用买一张4090自己跑。后来把账算清楚,这个念头就彻底断了。
1.1 算了一笔账:买显卡的钱够调几万次API
一张RTX 4090当时市场价约一万六,如果需要跑视频生成模型,一张还不一定够,因为视频模型显存占用比图像模型高得多,主流开源方案基本是24G起步,还可能要双卡。如果上A100,单卡价格直接奔着八九万去了,这还没算机箱、电源、散热和电费。
我们直接按业务量折算了一下。当时几个主流视频生成API的单次生成价格,大约在每条/每片段1到6块钱区间,假设我们一个月要产200条视频,每条视频平均拆成4到6个镜头片段,就算全部用API生成,一个月的直接成本大概在3000到8000块之间——比买一张4090便宜,而且不需要一次性掏一大笔钱。更关键的是,我们的产量并不是一直稳定的,有时候一天要20条,有时候一周只有3条。API是用的才收费,显卡是放着也折旧,这个逻辑差异对初创小团队非常致命。
1.2 省掉的隐性成本:模型更新、运维和失败重试
买显卡不只是买一块硬件,后面跟着一长串隐性成本。本地部署一套视频生成模型,驱动要匹配,CUDA版本要对,PyTorch环境经常因为依赖冲突整个崩掉,崩一次就得搭进去半天。模型开源的版本还未必是厂商最新最强的,更新一个版本,很可能又得重新做环境迁移。
这些我们是真的经历过。之前跑开源OCR模型的时候就遇到过一次,A机器上正常,B机器上莫名其妙报CUDA编译错误,最后发现是显卡驱动和cuDNN版本对不上。视频生成这种更重的负载,类似的问题只会更多。而官方API把这些全部包办了,模型更新、算力调度、失败重试是服务商的事,我只需要关心中间是否超时、是否限流,维护成本直线下降。
1.3 零显卡团队的底线思维
没有显卡,不等于所有AI环节都不能碰。我们的底线思维很简单:凡是重度依赖GPU的工作,比如视频生成、高质量图片生成,一律交给官方API;凡是CPU能扛住的,比如文本生成、语音转录、字幕对齐、视频无损裁剪拼接,全部用开源工具在本地解决。这样既能保住核心生产力,又能把成本压到最低。
我们还薅了不少免费额度的羊毛。比如新用户送的图片生成额度、语音合成免费次数、大模型API的体验包,都拿来跑早期调试。真正走到生产环境了,再切到付费档。这套组合拳打下来,从项目启动到第一版流水线跑通,产生的实际费用不到1000块钱。
2. 流水线整体长什么样:从需求到成片的五个环节
我们这条流水线,本质上是一条“文本进、视频出”的生产链路。整个过程被我拆成五个环节,每个环节尽量解耦,方便单独调试和替换。
2.1 需求输入与任务拆解
输入端的原始需求往往很糙,比如客户丢过来一句“帮我做一个30秒的防晒霜种草视频”。系统先调用大模型把这句话解析成结构化任务卡,包括:
- 视频主题和卖点关键词
- 目标时长与画面比例(横屏16:9还是竖屏9:16)
- 投放平台与对应风格(抖音偏快节奏,B站偏测评,小红书偏生活场景)
- 语气倾向(活泼、专业、沉稳)
这一步非常关键,因为后面所有环节都在吃这张任务卡的参数。早期我们为了省事,让人手工填参数,发现3个人光填表就能填到怀疑人生。后来改成大模型自动拆解,正确率大概能到85%,剩下15%人工修一下字段就能进下一步。
2.2 脚本分镜与素材描述生成
任务卡确认之后,交给文案模型生成分镜脚本。我们要求模型严格按JSON格式输出,每一行包含:镜头序号、镜头时长、画面内容描述、镜头运动方式、台词文本、字幕文本、背景音乐情绪。
这个环节最大的坑是模型输出格式不稳定。后来我们用了支持JSON Mode的API,并在System Prompt里给了非常具体的模板示例,才把解析失败率降到2%以下。分镜生成之后还有一道校验程序,检查镜头时长加起来是否等于总时长,台词和字幕是否为空,不通过就带着报错信息自动重试一次。
2.3 素材生成:文生图与图生视频的组合拳
素材生成是整个链路里最烧钱的环节,所以在保证效果的前提下,我们做了两个省钱操作。
第一,能先生成图片就先生成图片。纯文生视频的API普遍比图生视频贵,而且画面可控性差。我们先用图片模型按分镜描述生成关键帧,再拿关键帧作为首帧去生成短视频片段,这样既能把控画面构图,又能省一笔开销。
第二,尽量让每个镜头控制在5秒以内。很多视频API单次生成的最长时长是5秒或10秒,但越长越容易崩、越贵,失败重试成本也越高。我们统一把镜头切到4到5秒,既满足成片节奏,也降低了单次调用的失败风险。
2.4 配音、字幕与最终合成
所有镜头片段生成完毕后,并行处理三个任务:TTS语音合成生成画外音;根据台词文本生成字幕文件;用FFmpeg把多个片段无损拼接成一条完整视频。字幕这块我们走的是“先拿TTS时间戳对齐,再转成ASS字幕”的路线,比事后用Whisper做转录对齐要准得多,后面讲实现细节时我会展开。
2.5 质量检查与人工介入
合成完成后不能直接交片,因为AI生成的内容总会出现一些“开盲盒式”的问题。我们的质检程序会自动检查:视频分辨率是否达标、时长是否在误差范围内、字幕是否完整、是否存在全黑帧或全白帧、文件是否损坏。全部通过之后,再推给人工做最后一道快速审核。
人工审核这里是整个流水线里唯一没法完全自动化的人力环节。3个人轮流当审核员,平均一条视频花5到10分钟浏览一遍。虽然不能做到100%自动交付,但已经比从头做一条快了不止一个量级。
3. 工具选型逐个聊:哪个用官方API,哪个用开源项目
这个项目用到的东西很杂,我按环节梳理一下选型思路,顺便说说为什么每个位置最终选了那个方案。
| 环节 | 选型 | 类型 | 核心原因 |
|---|---|---|---|
| 文本生成/分镜 | DeepSeek官方API | 官方API | 便宜、上下文长、支持JSON输出 |
| 图片生成 | 国内某平台图片API | 官方API | 中文理解好、有免费额度 |
| 视频生成 | 国内某平台视频API | 官方API | 支持图生视频、排队时间可控 |
| 语音合成 | Azure TTS / 开源Edge TTS | 官方API + 开源 | 音色自然、有时间戳 |
| 视频拼接 | FFmpeg | 开源 | 功能全、免费、处理速度极快 |
| 字幕渲染 | Python + ASS | 开源自研 | 灵活、可精确控制样式 |
| 任务编排 | Python + Celery + Redis | 开源自研 | 可控性强、支持复杂重试 |
3.1 视频生成API:我们的横向对比结论
视频生成API我们前后试了四五家,包括可灵、即梦、智谱的CogVideoX接口、Runway,还有Pika。综合下来,我们优先选择的是国内平台的API,核心原因有三条:
一是中文语义理解明显更好。我们传分镜描述时会有大量中文场景词,比如“防晒霜在沙滩上被阳光照射”“镜头缓缓推进瓶身”,国内平台对这些描述的执行力明显强一些,画面生成的成功率肉眼可见地高。Runway和Pika对中文描述的理解就经常跑偏,得先翻译成英文再微调提示词,等于多一道工序。
二是付费和调用方式更符合国内团队习惯。国内平台支持支付宝直接充值,按次扣费,有清晰的用量明细,不用绑外币卡,不用考虑汇率损失。
三是排队和成功率相对稳定。我们实测几家平台在非高峰期,一个5秒镜头的平均排队时间在20秒到两分钟之间,成功率约在80%到90%。API返回失败时会有明确错误码,方便我们做自动重试。横向对比下来,我们最终主力用了一家响应速度和价格都居中的平台,另一家做备份,防止单点故障导致断流。
3.2 文案与脚本模型:DeepSeek和GLM的用法
文本生成我们一开始用的GLM,后来把大部分流量切换到了DeepSeek官方API。原因很直接:DeepSeek的新用户额度大,按tokens计费的价格也便宜。以生成一个30秒视频的分镜脚本为例,大约消耗3000到5000个tokens,成本基本可以忽略不计,在几毛钱以内。
DeepSeek我们最常用的是JSON结构化输出模式。你只要在请求体里开启JSON模式,再把分镜模板的示例塞进提示词,它就能稳定返回可解析的JSON。这个能力对于搭建流水线来说太重要了,如果没有JSON模式,脚本模型的输出还要再做一层自然语言解析,复杂度会翻倍。
GLM我们也留了一条通路,作为文案生成的备用模型。因为任何大模型API都有抽风的时候,一旦主力模型限流或报错,整个流水线不能停,就得靠备用通道顶上。我倾向于把这类容灾设计成在代码里预置多份配置,而不是等出问题了再手动切。
3.3 开源工具:FFmpeg、MoviePy、Celery和Redis
开源工具在这条流水线里扛起了最重的那部分活。
FFmpeg负责几乎所有视频处理:片段拼接、缩放、加黑边转竖屏、抽取关键帧做封面、提取音轨、静音检测。这些操作全部是CPU跑的,完全不依赖显卡,处理一条30秒1080P视频的拼接,基本是几秒钟的事。FFmpeg的命令行参数虽然反人类,但它稳定到可以用十年。
MoviePy没被我们放在主链路,主要用来做封面图和文字水印。比如从视频指定时间点截取一帧,盖上产品名和发布时间,通过MoviePy自带的时间轴滤镜生成一张带文字的封面图,比用PS人工做快得多。
任务编排层我们用的是Celery加Redis。Celery负责把每个视频任务拆成子任务派发给不同worker,Redis做消息队列和状态记录。举个例子,一条视频的全流程会被拆成“生成分镜”“生成图片”“生成视频片段”“合成音频”“拼接字幕”“质检”六个子任务,某个任务失败了,Celery会自动重试或者让下一个环节等待。这种模式的优点是整个流程可以被切成一个个小单元,单独重启也不会影响其他正在跑的任务。
3.4 为什么不用集成的低代码编排平台
这里多说一句。市面上像n8n、Dify这类AI工作流编排工具我们一开始也试过,界面拖拽确实方便,内置了各种API节点,二十分钟就能拼出一条demo。但真用到生产环境,发现两个问题:一是不够灵活,视频流水线的核心是失败重试、幂等控制、并发配额管理,低代码平台在自定义重试策略、错误码映射、并发配额上限制很多;二是难以本地批量调试,每次改完逻辑都要在网页端重新配置,团队协作起来非常别扭。
所以我们最终选择自己用Python写编排层,只把n8n和Dify保留在demo演示和轻量自动化场景里。这个决定现在看来完全正确,它让我们的流水线具备了对每一种API错误做精细处理的能力。
4. 编码实现:跑通流水线的关键细节
讲完了选型,说点代码层面的干货。以下实现都基于Python,你在自己搭的时候可以直接抄作业。
4.1 任务队列与并发上限的取舍
视频生成API不是普通的HTTP请求,它的调用模型是异步任务:先提交生成请求,拿到一个task_id,然后轮询另一个接口查询任务状态,等它变成“成功”后再下载视频文件。
如果我们像调普通接口一样并发几十个请求,很快就会被限流,甚至被临时封掉账号。我们实测下来,并发控制在2到4之间最稳妥。因为生成类API不仅有接口频率限制,还有总排队任务数限制,提交太快了反而让先提交的任务在队列里干等。
简单轮询的代码逻辑大概长这样:
import time import requests def submit_video_task(api_key, prompt, image_url=None): url = "https://api.example.com/v1/video/generate" headers = {"Authorization": f"Bearer {api_key}"} payload = {"prompt": prompt, "duration": 5} if image_url: payload["image_url"] = image_url resp = requests.post(url, headers=headers, json=payload) resp.raise_for_status() return resp.json()["task_id"] def poll_video_task(api_key, task_id, timeout=300, interval=5): url = f"https://api.example.com/v1/video/task/{task_id}" headers = {"Authorization": f"Bearer {api_key}"} start = time.time() while time.time() - start < timeout: data = requests.get(url, headers=headers).json() status = data.get("status") if status == "success": return data["video_url"] if status in ("failed", "canceled"): raise RuntimeError(f"任务失败: {data.get('error', '未知错误')}") time.sleep(interval) raise TimeoutError(f"任务 {task_id} 在 {timeout} 秒内未完成")这里的轮询间隔不要设得太短,5秒一次已经够了。设成1秒一次会让服务端认为你是恶意请求,反而更容易触发限流。
4.2 API调用参数里那些容易被忽略的坑
第一,时长单位。有的API时长参数是秒,有的是帧数,还有的是按分辨率不同要求“时长必须是5的倍数”。我们的SDK封装层会统一换算,比如收到“4秒”就把不同服务商对应成不同参数,避免手滑传错。
第二,上下文长度限制。这个坑我们踩得最狠。我们的脚本生成环节最初会把前一次的全部分镜文本都存进对话历史,再传给模型。结果在一次批量跑批时,突然报了一个400错误,提示里写着类似“this model's maximum context length is 1048576 tokens”的报错。当时我们全懵了,因为我们的文本总量根本没到一百万token。后来排查才发现,这个报错里的数字是模型上下文窗口上限,但真正触发的原因是请求里塞入了一个异常大的字段,比如某个分镜的图片描述被循环拼接了几百次,导致单次请求超过模型限制。解决思路很简单,在把大文本交给模型之前做截断或拆段处理,只保留当前环节真正需要的上下文。
第三,分辨率参数。我们推荐的竖屏视频平台会接受9:16的720P甚至1080P输出,但视频API里分辨率往往限制为“文本生视频720P、图生视频1080P”。传参之前要先确认接口文档,否则接口会直接静默降级成默认值,导致生成的素材分辨率对不齐。我们踩过一次,一条视频前半段是1080P后半段是720P,拼接出来客户直接打回。
4.3 视频拼接与字幕对齐的具体操作
FFmpeg拼接多段视频最稳妥的方法是concat demuxer,它可以避免中间过程的画质损失:
# 把待拼接的所有MP4路径写进文件列表 echo "file '/data/clips/clip_01.mp4'" > list.txt echo "file '/data/clips/clip_02.mp4'" >> list.txt # 执行无损拼接 ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4注意两点:所有待拼接的视频必须使用相同的编码格式、分辨率、帧率,否则-c copy会报错或产生花屏;如果有画幅不一致的片段,需要先用scale和pad滤镜统一画幅,再进入拼接环节。
字幕对齐我们用了更聪明的方案:在TTS合成语音时拿到每个句子的时间戳,然后直接生成ASS字幕文件,而不是生成视频后再用Whisper识别。因为Whisper转录虽然准确率高,但它是拿识别结果去猜时间戳,总会有几百毫秒到一两秒的误差,而TTS接口返回的时间戳是合成时精确计算的,误差极小。
如果拿不到TTS时间戳,兜底方案才是Whisper本地转录,用开源模型在CPU上跑,一条30秒音频转录大概5到10秒,也可以接受。
4.4 失败重试与幂等设计
自动重试是流水线稳定运行的命根子。我们的策略是所有子任务在执行前都生成一个唯一的任务ID,Redis里记录这个ID对应到哪一步、失败了几次、下次重试时间。这样即使某个API调用重复执行了,我们也能在业务逻辑上识别出这是同一批次的任务,避免生成重复素材。
重试策略上,我们使用的是指数退避加抖动:第一次失败等5秒重试,第二次等15秒,第三次等45秒。这个方法看起来原始,实际效果很好,既不会把服务商打崩,也能在限流解除后及时恢复。
但有一个特别注意:并不是所有失败都值得重试。如果是API返回“请求参数不合法”这种4xx错误,重试多少次都是白费,应该立刻终止并让人工介入修改分镜描述。如果是5xx或超时错误,才进入自动重试。我们的代码里面对错误码做了分类处理,这也是为什么不用低代码平台的原因之一。
5. 踩过的坑:限流、超时、报错与费用翻倍
任何流水线都会栽坑,这部分我按时间顺序把最典型的几个问题拉出来,每个都是真实经历过的。
5.1 没配Key的报错让人怀疑人生
第一次把文案模型接进整体流水线时,日志里疯狂刷一个报错:llm-deepseek: no api key for provider route "deepseek-official"。当时第一反应是DeepSeek的接口地址填错了,结果去控制台一看,Key根本没问题。查了快一个小时后才发现,问题出在编排平台的模型路由配置上——我们在应用里选了“DeepSeek官方版”,但provider的API Key是空的,平台在路由到这个provider时直接拦住了。
这个坑的典型特征是:报错信息里能看到“provider route”之类字眼,但控制台和模型供应商设置里找不到明确提示。解决办法是去检查每一个模型分发节点的环境变量和密钥配置,而不是盯着接口请求日志死磕。自那之后,我们把所有API Key统一收口到一个配置中心,不在多个文件里散落配置,出问题先从配置中心查一遍。
5.2 上下文超限:1048576 tokens的迷惑报错
这条在4.2里提过,再展开说一下。正常来说,一个支持百万token上下文的模型,普通项目很难触顶。但我们当时批量生成10个分镜,每个分镜的提示词里又不小心循环拼接了同一个产品资料块,导致单次请求的payload膨胀到几百万字符。这告诉我们一个道理:报错信息里的数字是上限,不是触发原因,真正要排查的是自己传了什么进去。
后来我们在每层调用前都加了一步“内容截断器”,对不同环节设定不同的最大长度:脚本生成8K字符、分镜描述16K字符、视频提示词2K字符。超过的部分要么截断,要么分两次调用。从那以后,这类400报错彻底消失。
5.3 视频生成API的限流和排队
服务商的限流不会提前通知你。最可怕的场景是下午客户急着要片,我们在同一时间段提交了30个视频任务,结果前10个正常返回,后面20个全部429限流。当时流水线没有做限流错误识别,直接把429当成普通错误来回重试,结果越重试越限流,最后连前面正常提交的任务都被连累取消了。
解决思路有两步:
- 把限流错误码(429)和过载错误码(503)单独识别,一旦出现就暂停当前批次的所有新任务,等待30到60秒再恢复。
- 在提交任务前做一个本地令牌桶,控制每分钟最多提交多少个任务,从源头避免持续触发限流。
我们最终把并发数压到3,每分钟提交数压到10,这个参数跑了两周都很稳定。
5.4 素材质量问题与内容合规
AI生成的素材不可能一直稳定,最常见的问题是画面出现乱码文字、畸形肢体、光影不一致。我们的质检程序只能检测技术指标,对审美问题无能为力,所以必须保留人工审核环节。另外还有一层容易被忽略的合规问题:如果生成的视频里出现了真实人物形象、商标、知名建筑,一旦用于商业投放,风险极高。我们现在的策略是,商用素材只生成虚拟角色和虚构场景,所有特写人物一律用平台明确的“虚构形象”标签,从源头规避。
6. 成本结算与效率报告:零显卡方案到底亏不亏
跑了大半年,这条流水线的经济账已经非常清晰了。
6.1 单条视频的真实成本拆分
一条30秒成品视频,我们的真实成本如下:
| 成本项 | 费用区间 | 说明 |
|---|---|---|
| 文案与分镜(大模型API) | 0.1元 | 单次解析约3000到5000 tokens |
| 图片生成(4张关键帧) | 1到2元 | 每张约0.3到0.5元 |
| 视频生成(4个5秒片段) | 6到12元 | 图生视频单段约1.5到3元 |
| TTS配音 | 0.2到0.5元 | 按字符数计费,约200字 |
| 字幕/拼接/质检 | 0元 | 纯开源工具本地执行 |
| 人工审核 | 约8到15分钟人力 | 按团队时薪折算,约3到5元 |
综合算下来,一条30秒成片的现金成本大约在7到15元,人工审核时间平均10分钟。一个月做200条,总现金成本不到3000元,人工工时约33个小时。这个数据对只有3个人的团队来说完全能接受。
6.2 与本地部署的对照
如果走本地部署,买一张4090要一万六,每月的电费、折旧、运维时间成本加起来至少一千元起步,而且要一个人兼职维护环境,一个月大概会搭进去两到三天工时。但本地部署换来的是什么?是一条视频生成成本变成几毛钱电费。只有当你的月产能达到数千条视频,本地部署才可能在单条成本上反超API方案。而月产能数千条视频意味着团队至少要扩到十人以上,这已经完全是另一个量级的业务了。
对我们这种预算有限、产能有限的小团队来说,API方案不仅是过渡方案,其实是可以长期依赖的生产方案。
6.3 产出速度与真实瓶颈
在运行稳定后,我们统计过一次:一条30秒视频从提交需求到拿到成片,平均耗时28分钟,其中视频生成排队占掉了20分钟左右。真正在本地处理环节只花了几分钟。这也说明,没有显卡并不是最大瓶颈,API的排队时长才是。
我们后来做了个优化:每晚用脚本自动提交第二天的任务,让深夜排队时间消化掉一部分生成任务,第二天早上团队到位直接审核。这个“错峰提交”策略让白天的交付时间压缩到15分钟以内,客户体感提升非常明显。
7. 最后再讲点实在的体会
这次搭建过程给我们的最大教训是:AI应用并不一定需要“被卡脖子”,没有显卡也能用最轻量的方式把流程跑起来。错过了本地部署,不代表错过了AI机会,关键看你能不能把需求拆成一个个API能解决的子问题。
如果你们团队也打算走这条路,我建议分三步走:先用免费额度把“文案到分镜到图片生成”的最小闭环跑通,再接入视频生成API并做好限流控制,最后再考虑并发编排和自动重试。不要一上来就追求全自动化,那会让自己困在低效的调试循环里。
我们下一步的计划,是把这套流水线再往前推一步:让内容审核Agent能自动发现画面异常并重新生成对应镜头,相当于把人工审核的负担再砍掉一半。3个人的小团队,如果能把重复劳动一步步交给代码,那就能腾出时间去做真正有创意的事情。希望这篇记录能给同样零硬件准备的团队一点信心。