ความสม่ำเสมอของตัวละครในวิดีโอ AI: โมเดลจดจำใบหน้าได้อย่างไร
เจาะลึกเชิงเทคนิคเกี่ยวกับนวัตกรรมที่รักษาอัตลักษณ์ของตัวละครข้ามช็อต ตั้งแต่กลไก attention ไปจนถึง identity embeddings

หนึ่งในความท้าทายที่คงอยู่ยาวนานที่สุดของการสร้างวิดีโอ 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 มีปัญหานี้อย่างเห็นได้ชัด ตัวละครอาจมีหน้าตาเปลี่ยนไป ดูแก่ขึ้นเล็กน้อยระหว่างช็อต หรือมีลักษณะเฉพาะที่ไม่สอดคล้องกัน ซึ่งผู้ปฏิบัติงานเรียกว่า "identity drift" จุดเปลี่ยนสำคัญเกิดจากการมองความสม่ำเสมอของตัวละครไม่ใช่ปัญหาสำหรับ post-processing แต่เป็นปัญหาด้านสถาปัตยกรรม
Identity-Preserving Embeddings: รากฐาน
นวัตกรรมหลักลำดับแรกคือการเพิ่ม identity embeddings เฉพาะที่คงอยู่ตลอดกระบวนการสร้าง แทนที่จะพึ่งพา text conditioning เพียงอย่างเดียว โมเดลในปัจจุบันจะรักษา identity tokens ที่ชัดเจนไว้:
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จากนั้น identity tokens เหล่านี้จะถูกใส่เข้าไปในกระบวนการ diffusion ทุก denoising step เพื่อสร้างสิ่งที่ผมชอบมองว่าเป็น "จุดยึด" คล้ายอุปกรณ์ป้องกันที่ติดตั้งไว้แน่นอนบนเส้นทางปีนเขา ซึ่งคุณสามารถคลิปกลับไปหาได้เสมอเมื่อสภาพการณ์เริ่มไม่แน่นอน
Cross-Frame Attention: การเรียนรู้อัตลักษณ์ตามเวลา
ความก้าวหน้าลำดับที่สองอยู่ที่สถาปัตยกรรม: โมเดลในปัจจุบันให้ attention ข้ามเฟรมอย่างชัดเจนเมื่อตัดสินใจเกี่ยวกับรูปลักษณ์ของตัวละคร Diffusion transformers รองรับสิ่งนี้ได้โดยธรรมชาติผ่านการประมวลผล spacetime patch แต่โมเดลที่มุ่งเน้นความสม่ำเสมอไปไกลกว่านั้น
นวัตกรรมสำคัญ: เลเยอร์ identity attention เฉพาะที่ให้ attention กับบริเวณใบหน้าข้ามมิติเวลาโดยเฉพาะ:
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กลไก triple-attention นี้ ซึ่งรวม spatial, temporal และ identity-specific attention เข้าด้วยกัน ช่วยให้โมเดลตัดสินใจเรื่องรูปลักษณ์โดยอ้างอิงอย่างชัดเจนทั้งอัตลักษณ์ที่กำหนดไว้และเฟรมก่อนหน้า
เปรียบเทียบแนวทางของโมเดลในปัจจุบัน
แพลตฟอร์มสร้างวิดีโอรายใหญ่ใช้วิธีรักษาความสม่ำเสมอของตัวละครต่างกัน:
| โมเดล | แนวทาง | วิธีรักษาความสม่ำเสมอ | ประสิทธิภาพ |
|---|---|---|---|
| Sora 2 | Spacetime patches | โดยนัยผ่าน context ที่ยาว | ดีสำหรับคลิปสั้น |
| Veo 3 | การสร้างหลายขั้นตอน | การยึดกับ keyframe | แข็งแกร่งสำหรับการเคลื่อนไหวของมนุษย์ |
| Gen-4.5 | Reference conditioning | การใส่อัตลักษณ์อย่างชัดเจน | ความสม่ำเสมอระดับแนวหน้า |
| Kling 1.6 | Face-aware attention | การติดตามใบหน้าเฉพาะทาง | แข็งแกร่งสำหรับภาพระยะใกล้ |
Gen-4.5 ของ Runway สมควรได้รับการกล่าวถึงเป็นพิเศษ แนวทางของพวกเขารวม reference image conditioning เข้ากับสิ่งที่เรียกว่า "identity locks" ซึ่งเป็น learned tokens ที่โมเดลได้รับการฝึกให้คงไว้ไม่ว่าการตัดสินใจเชิงสร้างสรรค์อื่นจะเป็นอย่างไร ตัวเลือกด้านสถาปัตยกรรมนี้น่าจะมีส่วนต่อความโดดเด่นใน Video Arena ของพวกเขา
กระบวนทัศน์ของ Reference Frame
การเปลี่ยนแปลงครั้งสำคัญในปี 2025 คือการหันไปสู่การสร้างแบบ reference-conditioned แทนที่จะสร้างตัวละครจากคำบรรยายข้อความล้วน ๆ โมเดลในปัจจุบันรับภาพอ้างอิงเพื่อกำหนดรูปลักษณ์มาตรฐาน:
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 videoพารามิเตอร์ identity_strength แสดงถึง trade-off ที่สำคัญ หากสูงเกินไป โมเดลจะตายตัวและไม่สามารถแสดงความแปรผันของสีหน้าตามธรรมชาติได้ หากต่ำเกินไป drift จะกลับมา การหาจุดสมดุล ซึ่งโดยทั่วไปอยู่ราว 0.7-0.85 เป็นทั้งศิลปะและวิทยาศาสตร์
Loss Functions สำหรับการรักษาอัตลักษณ์
การฝึกระบบเหล่านี้ต้องใช้ loss functions เฉพาะทางที่ลงโทษ identity drift อย่างชัดเจน:
Identity Preservation Loss:
L_identity = ||f(G(z, c)) - f(x_ref)||² + λ_temporal * Σ_t ||f(v_t) - f(v_{t+1})||²โดย f คือ pre-trained face recognition encoder, G คือ generator และ 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สถานการณ์หลายตัวละคร: ปัญหาที่ยากกว่า
ความสม่ำเสมอของตัวละครเดี่ยวได้รับการแก้ไขไปมากแล้ว สถานการณ์หลายตัวละคร ซึ่งต้องคงอัตลักษณ์หลายแบบที่แตกต่างกันในเวลาเดียวกัน ยังคงท้าทาย กลไก attention อาจผสมอัตลักษณ์เข้าด้วยกัน จนนำไปสู่การรั่วไหลของลักษณะเฉพาะระหว่างตัวละคร
แนวทางปัจจุบันใช้ identity banks แยกกัน:
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)separator tokens ทำหน้าที่เหมือนระบบ belay ระหว่างนักปีนเขา โดยคงอัตลักษณ์ให้แยกจากกันแม้ทำงานอยู่ใกล้กัน
นัยเชิงปฏิบัติสำหรับครีเอเตอร์
สำหรับผู้ที่ใช้เครื่องมือเหล่านี้แทนการสร้างเครื่องมือเอง มีรูปแบบการใช้งานเชิงปฏิบัติหลายประการที่ชัดเจนขึ้น:
คุณภาพของภาพอ้างอิง
ภาพอ้างอิงความละเอียดสูง มีแสงดี และมีสีหน้าเป็นกลาง ให้ผลลัพธ์ที่สม่ำเสมอกว่า โมเดลเรียนรู้อัตลักษณ์จากจุดยึดเหล่านี้ และ noise จะแพร่กระจายต่อไป
ภาพอ้างอิงหลายภาพ
การให้ภาพอ้างอิง 3-5 ภาพจากมุมต่างกันช่วยให้โมเดลสร้างตัวแทนอัตลักษณ์ที่สมบูรณ์ยิ่งขึ้น ลองนึกถึงการระบุตำแหน่งจากหลายจุด
Prompts ที่บรรยายอัตลักษณ์
คำบรรยายอัตลักษณ์อย่างชัดเจนใน prompts ช่วยเสริมความสม่ำเสมอทางภาพ "ผู้หญิงอายุ 30 ปี ผมสั้นสีน้ำตาลและตาสีเขียว" ให้ข้อจำกัดเพิ่มเติมที่โมเดลนำไปใช้ได้
วิธีตั้งค่าช็อตทีละขั้นตอน
- ขั้นตอนที่ 1: เลือก reference frame หนึ่งภาพที่ใบหน้าได้รับแสงสม่ำเสมอและมีสีหน้าเป็นกลาง แล้วใช้เป็น anchor สำหรับทุกช็อตในลำดับ
- ขั้นตอนที่ 2: เพิ่มภาพอ้างอิงอีกสองถึงสี่ภาพจากมุมอื่น เพื่อให้ identity embedding ถูก triangulate แทนที่จะคาดการณ์จากมุมมองเดียว
- ขั้นตอนที่ 3: บรรยายอัตลักษณ์ใน prompt ด้วยคำเดิมทุกครั้ง เพราะคำบรรยายที่เปลี่ยนไประหว่างช็อตจะนำความแปรปรวนที่ภาพอ้างอิงกำจัดไปแล้วกลับมาอีก
- ขั้นตอนที่ 4: สร้างการทดสอบสั้น ๆ ก่อนสร้างทั้งลำดับ แล้วเปรียบเทียบเฟรมแรกกับเฟรมสุดท้าย เพราะ drift สะสมขึ้นและตรวจจับได้คุ้มค่ากว่าที่สิบวินาทีแทนที่จะเป็นเก้าสิบวินาที
เส้นทางข้างหน้า
เรากำลังเข้าใกล้จุดที่วิดีโอซึ่งสร้างโดย AI สามารถรักษาความสม่ำเสมอของตัวละครได้เพียงพอสำหรับการเล่าเรื่อง ความท้าทายที่เหลืออยู่ รวมถึงความสม่ำเสมอของสีหน้าที่ละเอียดอ่อน การสร้างเนื้อหาระยะยาวเกิน 60 วินาที และปฏิสัมพันธ์ของหลายตัวละคร กำลังได้รับการแก้ไขอย่างจริงจัง
ที่ Bonega.ai เราสนใจเป็นพิเศษว่าการปรับปรุงความสม่ำเสมอเหล่านี้จะผสานเข้ากับความสามารถในการต่อขยายวิดีโอได้อย่างไร ความสามารถในการต่อขยายฟุตเทจที่มีอยู่โดยยังคงความสม่ำเสมอของตัวละครอย่างสมบูรณ์ เปิดโอกาสเชิงสร้างสรรค์ที่เมื่อ 12 เดือนก่อนยังไม่สามารถทำได้
ความสง่างามทางคณิตศาสตร์ของการปฏิบัติต่ออัตลักษณ์เป็นข้อกังวลระดับสถาปัตยกรรมโดยตรง แทนที่จะเป็นการแก้ไขภายหลัง สะท้อนถึงความเติบโตของวิธีคิดเกี่ยวกับการสร้างวิดีโอ คล้ายการตั้ง high camp ที่มีเสบียงพร้อมก่อนผลักดันสู่ยอดเขา การปรับปรุงพื้นฐานเหล่านี้ทำให้การเดินทางเชิงสร้างสรรค์ที่ยาวไกลและทะเยอทะยานยิ่งขึ้นในอนาคตเป็นไปได้
ความสม่ำเสมอของตัวละครไม่ใช่แค่ตัวชี้วัดทางเทคนิคเท่านั้น แต่เป็นรากฐานของการเล่าเรื่องด้วยภาพ และในปี 2025 รากฐานนั้นก็แข็งแรงพอให้ต่อยอดได้ในที่สุด
ควรใช้อะไร และเมื่อใด
identity embedding คือเวกเตอร์ขนาดกะทัดรัดที่เข้ารหัสว่าใบหน้าเป็นของใคร แทนที่จะเข้ารหัสว่าใบหน้านั้นมีลักษณะอย่างไรในเฟรมหนึ่ง การเลือกเครื่องมือจึงหมายถึงการเลือกวิธีที่เครื่องมือนั้นจัดการกับเวกเตอร์ดังกล่าว
- ช็อตเล่าเรื่องสั้นที่มีตัวละครเดิมหนึ่งตัว: โมเดล reference-frame คือทางเลือกที่เหมาะสม เป็นแนวทางที่รักษาอัตลักษณ์ได้เชื่อถือที่สุดเมื่อความยาวต่ำกว่าสิบวินาที และ anchor frame ให้สิ่งที่ชัดเจนสำหรับปรับแก้เมื่อช็อตหนึ่งผิดพลาด
- ลำดับที่ยาวเกินหนึ่งนาที: คาดว่าจะเกิด drift ไม่ว่าโมเดลใด และวางแผนตัดต่อไว้ การสร้างเป็นช่วงสั้น ๆ แล้วเชื่อมต่อกันใช้เวลาน้อยกว่าการต่อสู้กับ render ยาวชิ้นเดียวที่เสื่อมคุณภาพในช่วงหนึ่งในสามท้าย
- มีตัวละครสองตัวขึ้นไปในเฟรม: ให้ถือว่า identity leakage เป็นผลลัพธ์เริ่มต้นและทดสอบตั้งแต่เนิ่น ๆ เพราะความล้มเหลวไม่ได้เกิดขึ้นอย่างค่อยเป็นค่อยไป แยกตัวละครออกเป็นคนละช็อตทุกครั้งที่การตัดต่อเอื้อให้ทำได้
- รูปลักษณ์สมจริงของบุคคลจริง: ไม่มีวิธีใดในนี้เชื่อถือได้พอที่จะรับปากกับลูกค้า และความเสี่ยงทางกฎหมายเป็นปัญหาแยกต่างหากจากปัญหาทางเทคนิค
สรุปอย่างตรงไปตรงมาคือ อัตลักษณ์ได้รับการแก้ไขดีพอสำหรับการเล่าเรื่องแล้ว แต่ยังไม่ดีพอสำหรับการผลิตแบบปล่อยทิ้งไว้โดยไม่ดูแล หากลำดับของคุณสั้น มีตัวละครเดียว และคุณตรวจทานทุกช็อตได้ โมเดลเหล่านี้จะรักษาอัตลักษณ์ไว้ได้ หากข้อใดข้อหนึ่งในสามข้อนี้ไม่เป็นจริง ให้เผื่องบสำหรับการถ่ายซ้ำ



