AI视频的人物一致性:模型如何记住面孔
深入剖析镜头间人物身份保持技术。从注意力机制到身份嵌入的架构创新深度分析。

在AI视频生成中,最令人头疼的问题之一就是在多个镜头中保持人物的一致性。任何电影制作者都会同意:当主角的面孔在切镜之间微妙地变化时,故事就会失去说服力。到了2025年,我们终于看到模型通过一些优雅的架构创新解决了这个问题,这些创新就像精心规划的攀岩路线一样精妙。让我为你介绍现代视频模型是如何学会记住面孔的。
一致性的挑战
传统的扩散模型通过概率采样生成每一帧。这会引入方差——虽然对多样性有益,但对身份识别就有害了。在生成10秒视频(24fps)时,模型需要做240个连续的决策,每一个都可能产生偏差。
# 核心问题:每个去噪步骤都会引入方差
def denoise_step(x_t, model, t):
noise_pred = model(x_t, t)
# 这个采样步骤引入了随机性
x_t_minus_1 = scheduler.step(noise_pred, t, x_t).prev_sample
return x_t_minus_1 # 细微的变化在帧之间逐渐累积早期的视频模型,如Gen-1和Pika 1.0,在这方面存在明显的困难。人物会在外观上有所变化,在镜头之间看起来会衰老,或显示出不一致的特征——这就是从业者所说的"身份漂移"。突破来自于把人物一致性不仅看作后处理问题,而是看作架构问题。
身份保留嵌入:基础
第一个重大创新是引入了在整个生成过程中持续的专用身份嵌入。与其仅仅依赖文本条件,模型现在维护显式的身份令牌:
class IdentityEncoder(nn.Module):
def __init__(self, embed_dim=768):
super().__init__()
self.face_encoder = FaceRecognitionBackbone() # 预训练的人脸模型
self.projection = nn.Linear(512, embed_dim)
self.identity_bank = nn.Parameter(torch.randn(32, embed_dim))
def encode_identity(self, reference_frame):
# 从参考帧中提取身份特征
face_features = self.face_encoder(reference_frame)
identity_embed = self.projection(face_features)
# 与学习的身份令牌进行交叉注意
identity_tokens = self.cross_attention(
query=self.identity_bank,
key=identity_embed,
value=identity_embed
)
return identity_tokens然后,这些身份令牌在扩散过程的每个去噪步骤中被注入,创建了我喜欢称之为"锚点"的东西——就像攀岩路线上的固定保护装置,当条件不确定时,你总是可以回到这些点。
跨帧注意力:学习时间身份
第二个突破是架构上的:模型现在在做关于人物外观的决定时明确跨帧注意。扩散变换器通过其时空补丁处理自然支持这一点,但以一致性为重点的模型更进一步。
关键创新: 专门的身份注意层,在时间维度上特别关注面部区域:
class IdentityAwareAttention(nn.Module):
def __init__(self, dim, num_heads=8):
super().__init__()
self.spatial_attn = nn.MultiheadAttention(dim, num_heads)
self.temporal_attn = nn.MultiheadAttention(dim, num_heads)
self.identity_attn = nn.MultiheadAttention(dim, num_heads)
def forward(self, x, identity_tokens, face_masks):
# 帧内的标准空间注意力
x = self.spatial_attn(x, x, x)[0] + x
# 帧间的时间注意力
x = rearrange(x, '(b t) n d -> (b n) t d', t=num_frames)
x = self.temporal_attn(x, x, x)[0] + x
x = rearrange(x, '(b n) t d -> (b t) n d', n=num_patches)
# 使用面部区域进行身份特定的注意力
face_tokens = x * face_masks.unsqueeze(-1)
x = self.identity_attn(
query=x,
key=identity_tokens,
value=identity_tokens
)[0] + x
return x这种三层注意机制——空间、时间和身份特定——使模型能够在明确参考既定身份和之前帧的同时做出外观决策。
当前模型方法对比
主要的视频生成平台以不同的方式实现了人物一致性:
| 模型 | 方法 | 一致性方法 | 效果 |
|---|---|---|---|
| Sora 2 | 时空补丁 | 通过长上下文隐式实现 | 适合短片段 |
| Veo 3 | 多阶段生成 | 关键帧锚定 | 人体动作表现强 |
| Gen-4.5 | 参考条件 | 显式身份注入 | 一致性最佳 |
| Kling 1.6 | 人脸感知注意力 | 专门面部追踪 | 特写表现强 |
Runway的Gen-4.5在这里值得特别提及。他们的方法结合了参考图像条件和他们称之为"身份锁"的东西——学习的令牌,模型被训练为无论其他生成决策如何都要保留。这种架构选择很可能是他们在视频竞技场获得主导地位的原因。
参考帧范式
2025年的一个重大转变是向参考条件生成的转变。与其纯粹从文本描述生成人物,模型现在接受建立规范外观的参考图像:
class ReferenceConditionedGenerator:
def __init__(self, base_model, identity_encoder):
self.model = base_model
self.identity_encoder = identity_encoder
def generate(self, prompt, reference_images, num_frames=120):
# 从参考图像中编码身份
identity_embeds = []
for ref in reference_images:
identity_embeds.append(self.identity_encoder(ref))
# 汇总多个参考以获得更稳健的身份
identity_tokens = torch.stack(identity_embeds).mean(dim=0)
# 使用身份条件进行生成
video = self.model.generate(
prompt=prompt,
num_frames=num_frames,
cross_attention_kwargs={
"identity_tokens": identity_tokens,
"identity_strength": 0.8 # 在一致性和创意之间取得平衡
}
)
return videoidentity_strength参数代表了一个重要的权衡。设置过高,模型会变得僵化,无法展示自然的表情变化。设置过低,漂移就会回归。找到最佳点——通常在0.7-0.85之间——既是艺术,也是科学。
身份保留的损失函数
训练这些系统需要专门的损失函数,明确惩罚身份漂移:
身份保留损失:
L_identity = ||f(G(z, c)) - f(x_ref)||² + λ_temporal * Σ_t ||f(v_t) - f(v_{t+1})||²其中f是预训练的人脸识别编码器,G是生成器,v_t代表生成的帧。第一项确保生成的面孔与参考相匹配;第二项惩罚帧间的变化。
def identity_preservation_loss(generated_video, reference_faces, face_encoder):
# 每帧与参考的身份匹配
frame_losses = []
for frame in generated_video:
face_embed = face_encoder(frame)
ref_embed = face_encoder(reference_faces).mean(dim=0)
frame_losses.append(F.mse_loss(face_embed, ref_embed))
reference_loss = torch.stack(frame_losses).mean()
# 相邻帧间的时间一致性
temporal_losses = []
for i in range(len(generated_video) - 1):
curr_embed = face_encoder(generated_video[i])
next_embed = face_encoder(generated_video[i + 1])
temporal_losses.append(F.mse_loss(curr_embed, next_embed))
temporal_loss = torch.stack(temporal_losses).mean()
return reference_loss + 0.5 * temporal_loss多人物场景:更难的问题
单人物一致性基本上已经得到解决。多人物场景——其中必须同时维护多个不同的身份——仍然是个挑战。注意力机制可能会混淆身份,导致特征在人物之间流动。
目前的方法使用单独的身份库:
class MultiCharacterIdentityBank:
def __init__(self, max_characters=8, embed_dim=768):
self.banks = nn.ModuleList([
IdentityBank(embed_dim) for _ in range(max_characters)
])
self.character_separator = nn.Parameter(torch.randn(1, embed_dim))
def encode_multiple(self, character_references):
all_tokens = []
for idx, refs in enumerate(character_references):
char_tokens = self.banks[idx].encode(refs)
# 添加分隔符以防止混淆
char_tokens = torch.cat([char_tokens, self.character_separator])
all_tokens.append(char_tokens)
return torch.cat(all_tokens, dim=0)分隔符令牌的作用就像攀岩者之间的保护站——即使在紧密接近时也能保持不同的身份。
对创意工作者的实际意义
对于那些使用而非构建这些工具的人来说,几个实用的模式已经出现:
参考图像质量很重要: 分辨率更高、照明良好、表情中立的参考图像会产生更一致的结果。模型从这些锚点学习身份,噪声会传播。
多个参考提高稳健性: 从不同角度提供3-5张参考图像可以帮助模型建立更完整的身份表示。把它想象成从多个点三角测量一个位置。
提示工程以实现一致性: 提示中明确的身份描述可以强化视觉一致性。"一位30岁的短褐色头发、绿眼睛的女性"提供了模型可以利用的额外约束。
前进的道路
我们正在接近一个阈值,在这个阈值上AI生成的视频可以保持足够用于叙事讲故事的人物一致性。剩余的挑战——微妙的表情一致性、超过60秒的长期生成和多人物交互——正在被积极解决。
在Bonega.ai,我们对这些一致性改进如何与视频扩展能力融合特别感兴趣。在保持完美人物一致性的同时扩展现有素材的能力开启了12个月前根本不可行的创意可能性。
把身份视为一流架构关注而非事后修正的数学优雅,标志着我们如何思考视频生成的成熟。就像在冲顶前建立设备完善的高营地,这些基础改进使得更长、更雄心勃勃的创意之旅成为可能。
人物一致性不仅仅是一个技术指标——它是视觉讲故事的基础。在2025年,这个基础终于变得足够坚实,可以在其上建设。
相关文章
继续探索这些相关文章



