AI 影片中的角色一致性:模型如何記住臉孔
深入探討從注意力機制到身分嵌入,如何在鏡頭之間維持角色身分的技術創新。

AI 影片生成中最持久的挑戰之一,是在不同鏡頭之間維持角色一致性。問問任何電影工作者就知道:主角的臉一旦在剪接之間出現細微變化,故事就會瞬間失去說服力。到了 2025 年,我們終於看到模型透過架構創新破解了這個問題,其精妙程度宛如精心規劃一條攀登困難山峰的路線。以下帶你了解現代影片模型如何學會記住臉孔。
一致性的挑戰
傳統 diffusion 模型透過機率取樣生成每一幀。這會引入變異,雖然有助於多樣性,卻會對身分一致性造成問題。生成一段 10 秒、24fps 的影片時,模型會做出 240 次連續決策,每一次都有可能產生漂移。
# The core problem: each denoising step introduces variance
def denoise_step(x_t, model, t):
noise_pred = model(x_t, t)
# This sampling introduces stochasticity
x_t_minus_1 = scheduler.step(noise_pred, t, x_t).prev_sample
return x_t_minus_1 # Slight variations accumulate over frames早期影片模型如 Gen-1 和 Pika 1.0 明顯難以處理這件事。角色的外觀會改變、在不同鏡頭間略微老化,或出現不一致的特徵,實務工作者將此稱為「身分漂移」。突破點在於,將角色一致性視為架構問題,而非後製問題。
保留身分的嵌入:基礎
第一項重大創新,是引入能在整個生成過程中持續存在的專用身分嵌入。模型不再只依賴文字條件,而是維持明確的身分 token:
class IdentityEncoder(nn.Module):
def __init__(self, embed_dim=768):
super().__init__()
self.face_encoder = FaceRecognitionBackbone() # Pre-trained face model
self.projection = nn.Linear(512, embed_dim)
self.identity_bank = nn.Parameter(torch.randn(32, embed_dim))
def encode_identity(self, reference_frame):
# Extract identity features from reference
face_features = self.face_encoder(reference_frame)
identity_embed = self.projection(face_features)
# Cross-attend with learned identity tokens
identity_tokens = self.cross_attention(
query=self.identity_bank,
key=identity_embed,
value=identity_embed
)
return identity_tokens這些身分 token 隨後會在每個去噪步驟注入 diffusion 過程,形成我喜歡稱為「錨點」的機制,就像攀岩路線上的固定保護點,當情況變得不確定時,隨時都能重新扣回去。
跨幀注意力:學習時間維度上的身分
第二項突破來自架構:模型如今在決定角色外觀時,會明確地跨幀關注資訊。Diffusion transformers 透過時空 patch 處理自然支援這項能力,但著重一致性的模型更進一步。
**關鍵創新:**專門針對時間維度中臉部區域進行關注的身分注意力層:
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):
# Standard spatial attention within frames
x = self.spatial_attn(x, x, x)[0] + x
# Temporal attention across frames
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)
# Identity-specific attention using face regions
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 | 時空 patch | 透過長上下文隱式維持 | 適合短片段 |
| Veo 3 | 多階段生成 | 關鍵影格錨定 | 對人類動作表現強 |
| Gen-4.5 | 參考條件化 | 明確注入身分 | 頂尖的一致性 |
| Kling 1.6 | 臉部感知注意力 | 專用臉部追蹤 | 適合特寫鏡頭 |
Runway 的 Gen-4.5 值得特別一提。他們的方法結合參考圖像條件化與所謂的「身分鎖定」,也就是模型經訓練後會保留的學習 token,不受其他生成決策影響。這項架構選擇很可能促成了他們在 Video Arena 的主導地位。
參考影格典範
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):
# Encode identity from reference images
identity_embeds = []
for ref in reference_images:
identity_embeds.append(self.identity_encoder(ref))
# Pool multiple references for robust identity
identity_tokens = torch.stack(identity_embeds).mean(dim=0)
# Generate with identity conditioning
video = self.model.generate(
prompt=prompt,
num_frames=num_frames,
cross_attention_kwargs={
"identity_tokens": identity_tokens,
"identity_strength": 0.8 # Balances consistency vs creativity
}
)
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):
# Per-frame identity matching to reference
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 consistency between adjacent frames
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)
# Add separator to prevent conflation
char_tokens = torch.cat([char_tokens, self.character_separator])
all_tokens.append(char_tokens)
return torch.cat(all_tokens, dim=0)分隔 token 的作用就像攀登者之間的確保,即使彼此距離很近,也能維持不同的身分。
對創作者的實務影響
對於使用這些工具而非建構它們的人來說,已經出現幾種實用模式:
參考圖像品質
高解析度、光線充足且表情自然的參考圖像,能產生更一致的結果。模型會從這些錨點學習身分,而雜訊也會隨之傳播。
多個參考資料
提供 3-5 張不同角度的參考圖像,有助於模型建立更完整的身分表徵。可將它想成從多個點定位一個位置。
描述身分的提示詞
在提示詞中明確描述身分,能強化視覺一致性。「一位 30 歲、留著棕色短髮且有綠色眼睛的女性」為模型提供了可利用的額外限制。
如何逐步設定一個鏡頭
- 步驟 1:選擇一張臉部光線均勻、表情自然的參考影格,並將它作為序列中每個鏡頭的錨點。
- 步驟 2:從其他角度再加入兩到四張參考圖像,讓身分嵌入透過三角定位建立,而非由單一視角外推。
- 步驟 3:每次都在提示詞中以相同措辭描述身分,因為在鏡頭之間變動描述,會重新引入參考資料原本消除的變異。
- 步驟 4:在生成完整序列前先生成短測試,並比較第一幀與最後一幀,因為漂移會累積,在十秒時發現問題比在九十秒時發現更省成本。
未來展望
我們正接近一個門檻,AI 生成影片已能維持足以支援敘事故事的角色一致性。剩餘挑戰包括細微表情的一致性、超過 60 秒的長篇生成,以及多角色互動,目前都正積極處理中。
在 Bonega.ai,我們特別關注這些一致性改進如何與影片延伸能力整合。在維持完美角色一致性的同時延伸既有影像,開啟了 12 個月前根本不可行的創作可能性。
將身分視為一項一級架構考量,而非事後修正,其數學上的優雅標誌著我們思考影片生成方式的成熟。這就像在攻頂前建立補給充足的高山營地,這些基礎改進讓未來更長、更具野心的創作旅程成為可能。
角色一致性不只是技術指標,它是視覺敘事的基礎。而在 2025 年,這個基礎終於變得足夠穩固,可以在其上建構更多內容。
該使用什麼,以及何時使用
身分嵌入是一種緊湊向量,編碼的是一張臉屬於誰,而非它在單一影格中的樣貌。選擇工具,就是選擇它如何處理這個向量。
- **具有一名重複出現角色的短篇敘事鏡頭:**參考影格模型是正確選擇。在十秒以內,這種方法最能可靠維持身分,而當某個鏡頭出錯時,錨定影格能讓你有明確的迭代依據。
- **超過一分鐘的序列:**無論使用哪種模型都應預期漂移,並規劃剪接。以較短片段生成再進行拼接,比起對抗一段在最後三分之一開始劣化的長時間渲染,更省時間。
- **畫面中有兩名或更多角色:**應將身分滲漏視為預設結果並及早測試,因為這種失敗不是漸進式的。只要剪輯允許,就在不同鏡頭中分開角色。
- **真實人物的寫實肖像:**這些方法都還不夠可靠,無法向客戶承諾結果,而法律風險是獨立於技術問題之外的另一回事。
誠實的總結是,身分一致性如今已足以支援敘事,但尚不足以支援無人監督的製作。如果你的序列很短、只有單一角色,且你能檢查每一個鏡頭,這些模型就能維持穩定。如果三項條件中任何一項不成立,就應預留重拍的預算。



