角色 Embedding 技术入门:AI 视频角色锁定的底层原理
面向工程师的技术入门:现代 AI 视频技术栈中角色 embedding 系统的架构、设计取舍、失败模式和未解决的开放问题。
本文写给工程师—研究员、ML 实践者、以及搭建或评估 AI 视频技术栈的开发者。如果你想要的是面向非技术读者的"为什么角色一致性重要"的总览,请从 完整指南开始。
这里我们讨论现代 AI 视频系统中角色 embedding 是如何工作的:架构、设计取舍、失败模式,以及尚未被很好解决的一些开放问题。
问题陈述
给定一个生成式视频模型 M 和一个角色 C,我们希望存在一种方法:对任何引用 C 的提示词序列 p_1, p_2, …, p_n,生成的输出都保持 C 的身份。
最朴素的做法—在每个提示词里加上角色描述—行不通,因为扩散采样是随机的,而提示词描述的是类别(category)而非身份(identity)。每次生成都是从"匹配该描述的有效角色分布"里抽一次样;身份会在多次抽样间漂移。
我们需要的是一种把模型输出条件化到一个具体的、已学习好的身份上的机制,而不仅仅是条件化到一段描述上。
架构
一个现代角色一致性系统通常包含 6 个组件:
1. 特征抽取(Feature extraction) — 从参考图产出身份 embedding
2. 存储(Storage) — 把 embedding 持久化并绑定 character_id
3. Negative prompt 合成 — 基于漂移目录自动生成 negative_prompts
4. Conditioning 注入 — 把 embedding 注入到模型 conditioning
5. 生成(Generation) — 用条件化模型做扩散采样
6. 一致性校验(Consistency verification)— 事后做相似度校验,必要时重生下面逐一展开。
1. 特征抽取
角色上传时,对参考图跑多个专门模型:
- 人脸编码器:ArcFace、FaceNet 或类似模型。输出一个 512 维身份 embedding,针对人脸识别优化,捕捉身份不变特征。
- 体形解析器:PIFu 或 Sapiens,提取身体比例与姿态。低维向量编码身高、体型、姿态。
- 外观编码器:CLIP 图像编码器,处理发色、肤色、衣着风格。768 维语义 embedding。
- 风格分类器:单独编码参考图属于写实、风格化、动画等。小型类别向量。
将上述向量拼接(或通过 attention 融合)成一个高维角色 embedding e_C。总维度通常在 1500-3000 之间。
为什么用多个模型而不是一个?因为身份是多轴的,没有单一编码器能完整覆盖。人脸编码器擅长"是不是同一张脸",但对身体比例无感。体形解析器对面部细节无感。CLIP 擅长语义层面的外观,但会丢失精细身份。拼起来才能拿到正交覆盖。
取舍:抽取流水线越复杂,上传时算力开销越大(业内一些方案在 30-90 秒级)。对面向消费者的工具是可接受的。对高吞吐量场景,可以在上传时一次性预计算 embedding,生成时直接引用。
2. 存储
每个角色以 (character_id, embedding_vector, metadata) 形式存储。元数据包含:
- 原始参考图(用于调试和重新抽取)
- 归属用户 / 项目
- 子变体指针(详见后文形态变体一节)
- 风格锚点(用于跨风格场景)
- 漂移模式覆写列表(按角色定制)
存储一般用向量数据库(Pinecone、Qdrant、Weaviate)或自研的索引结构。查询要快—亚 100ms—因为每次生成都会触发。
对隐私敏感的部署,embedding 可以按租户密钥加密存储。抽取过程是单向函数(无法从 embedding 反推参考图),但对处理真实人物的系统而言,把 embedding 当作 PII(个人身份信息)对待是合理的默认值。
3. Negative prompt 合成
这是系统里非显然但工程量最大的部分。
业内的做法是维护一份常见漂移模式(drift mode)目录—从大量生成里观察到的、可分类的失败类型。每个模式对应一段 negative_prompt 片段,用来抑制对应的失败。
目录里的一些示例:
| 漂移模式 | Negative prompt 片段 |
|---|---|
| 眼睛颜色漂移(棕 → 绿) | "green eyes, hazel eyes"(参考为棕色时) |
| 下颌线变窄 | "narrow jaw, weak chin, soft jawline" |
| 发际线后退 | "high hairline, thinning hair, receding hairline" |
| 肤色变暖 | "warm skin tone, golden complexion"(参考为冷色时) |
| 不对称蔓延 | "asymmetric face, uneven features" |
| 眼距漂移 | "wide-set eyes, close-set eyes" |
建立这个目录需要标注数据。业内一些团队会从公开 AI 视频工具(Runway、Pika、Sora 等)的生成结果里采上万条样本,标注出现的具体漂移模式。聚类后通常能得到约 30 个不同模式,覆盖约 85% 的可观测漂移。
对每次生成,系统会:
- 检索该角色的参考属性
- 计算各属性的"反向值"(例如参考为深色眼睛,反向是浅色眼睛)
- 组装出该角色专属的 negative prompt,把相关漂移抑制项串起来
由此得到的 conditioning 信号比纯靠提示词的版本要强得多。
4. Conditioning 注入
不同的视频模型对 conditioning 的接入方式不同:
- 基于参考图的模型(多数公开 API):可以传一张参考图;做法是把 embedding 通过一个学习好的投影编码回一张"合成参考图",再把它传进去。
- 仅文本 conditioning:把 embedding 通过软提示词(soft-prompt)投影传入。
- API 级模型访问(少数情况下可用):直接把 embedding 注入到 cross-attention 层,类似 IP-Adapter 的条件化方式。
一般而言,API 级注入比基于参考图的方式有效得多,但多数公开 API 不开放这种深度。在公开 API 暴露的接口面上工作时,把强 negative prompt 和"通过参考图编码进去的 embedding"组合起来,能拿到大约 80-90% 的 API 级注入效果。
这也是为什么在不掌控底层模型的情况下,搭一层角色一致性仍然是有意义的—公开 API 已经暴露的 conditioning 接口面上,仍有大量可挖掘的空间。
5. 生成
标准扩散采样,区别在于此时 conditioning 是以下几项的组合:
- 原始提示词(场景、动作、构图)
- 角色 embedding(按上述机制注入)
- Negative prompt(自动合成)
- 风格锚点(如果该段适用)
生成开销通常是普通生成的 1.0-1.2×,边际成本很小。
6. 一致性校验
生成完后,跑一个独立的身份模型(通常就是步骤 1 里那个人脸编码器)对输出做特征抽取。计算输出身份 embedding 与原参考 embedding 的余弦相似度(cosine similarity)。
阈值通常取 0.85。高于阈值即接受输出。低于阈值则触发重生,并提高 negative prompt 权重、加大 embedding 注入强度。
这层平均增加 5-10% 生成开销(多数镜头一遍过),但能挡住最严重的漂移,避免它们到达用户。
什么有效,什么仍困难
有效的部分:
- 单角色 30+ 镜头的高一致性,常规场景变化
- 跨项目的角色库复用(一次抽取,无限复用)
- 跨场景一致性(同一 character_id,在合理范围内的不同场景 / 风格里身份保持)
- 特征差异明显的多角色场景(不同年龄、性别、族裔)
仍困难的部分:
- 形态变体(form variants):同一角色但受伤、变老、换装等。常见做法是用基于主 embedding 的子 embedding,主 embedding 编码身份不变量、子 embedding 编码差量。中等变化下有效;大变形(例如同一角色的 8 岁版本)下会崩。
- 多角色身份串台:当两个锁定角色同框且特征相近(比如都是 30 岁亚裔女性),约 10% 的生成会出现部分特征互串。
- 跨风格连贯性:把锁定的写实角色放进风格化的"水彩"段。借助逐段风格锚点能部分解决,但退化仍然可见。
- 动物 / 非人类角色:同套架构适用,但人脸编码器在非人脸场景下质量明显下滑。
- 超过 ~3 分钟的长片连贯性:单镜抑制有效,但跨 50+ 镜头累积的细微差异,对仔细的观众而言仍可能造成可见的不一致。
开放研究问题
如果你也在这个方向上做事,有几个值得解的问题:
- 形态变体下的身份不变量。什么样的可学习表示能既捕捉身份不变的面部结构,又允许任意状态变换?
- 采样过程中的实时漂移检测。当前的一致性校验都是事后的。能否在扩散过程中检测漂移并在采样中途纠正?
- 隐式 vs 显式身份的取舍。什么时候训一个小的 per-character LoRA 优于基于 embedding 的条件化?分界点在哪?
- 多角色交互建模。不仅锁住两个身份,还要让他们之间的关系动态在跨镜头中也保持一致,怎么做?
- 身份不确定性量化。当模型对身份不确定时,能否把这种不确定性输出出来,而不是产出一个自信的漂移结果?
如果你正在做上述任何一项并希望交流,Juying 团队真心感兴趣。欢迎联系。
给 builder 的实战建议
如果你打算自己给产品搭一层角色一致性,三条建议:
1. 从 negative prompt 目录开始。这是性价比最高的一招。不需要 API 级模型访问;negative prompt 是任何公开 API 都暴露的接口。花一周时间标 1000 条生成结果,就能拿到一个覆盖大多数漂移的目录。
2. 不要低估事后校验。加一个简单的"相似度 < 0.85 就重生"循环,能挡掉最差的 10% 失败,并显著提升观感质量。这是从 90/100 到 95/100 最便宜的一档提升。
3. 早点投资存储。把角色 embedding 当作持久化资产,是会复利的架构洞见。把对的原语建好一次,未来所有功能(风格锁、场景库、资产复用)都能自然延伸。
相关阅读
如果你也在做这一块、想聊聊—info@juying.art