Постоянство персонажей в ИИ-видео: как модели учатся помнить лица
Технический разбор архитектурных инноваций, позволяющих моделям видеогенерации сохранять идентичность персонажей между кадрами, от механизмов внимания до эмбеддингов, сохраняющих идентичность.

Одна из самых упорных проблем в генерации видео с помощью ИИ—сохранение постоянства внешнего облика персонажа между кадрами. Спросите любого кинематографиста: история разваливается в момент, когда лицо главного героя едва заметно меняется между монтажными переходами. В 2025 году модели наконец-то решили эту задачу с помощью архитектурных инноваций, которые элегантны, как хорошо спланированный маршрут по сложной горе. Позвольте мне рассказать вам, как современные видеомодели учатся помнить лица.
Проблема постоянства
Традиционные модели диффузии генерируют каждый кадр с вероятностным семплированием. Это вносит вариативность—полезную для разнообразия, проблемную для идентичности. При генерации 10-секундного видео на 24 кадрах в секунду модель принимает 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's Gen-4.5 заслуживает отдельного упоминания. Их подход объединяет кондиционировку по референсному изображению с так называемыми "блокировками идентичности"—выученными токенами, которые модель обучена сохранять независимо от других решений генерации. Этот архитектурный выбор, вероятно, сыграл ключевую роль в их доминировании в 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):
# Кодирование идентичности из референсных изображений
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 videoПараметр identity_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 лет с короткими коричневыми волосами и зелёными глазами" даёт дополнительные ограничения, которые модель может использовать.
Дорога вперёд
Мы приближаемся к порогу, где генерируемое ИИ видео может поддерживать постоянство персонажей, достаточное для рассказывания историй. Оставшиеся задачи—консистентность тонких выражений, долгоформатная генерация более 60 секунд и взаимодействие между персонажами—активно разрабатываются.
В Bonega.ai мы особенно интересуемся тем, как эти улучшения постоянства интегрируются с возможностями расширения видео. Способность расширять существующие материалы с идеальным сохранением постоянства персонажей открывает творческие возможности, которые просто не были осуществимы 12 месяцев назад.
Математическая элегантность рассмотрения идентичности как архитектурной проблемы первого порядка, а не как постфактум коррекции, отражает зрелость нашего подхода к генерации видео. Как и установление хорошо снабжённого высокого лагеря перед штурмом вершины, эти фундаментальные улучшения позволяют более длинные и амбициозные творческие проекты, которые ждут нас впереди.
Постоянство персонажей—это не просто технический показатель. Это основание визуального рассказывания. И в 2025 году это основание, наконец, стало достаточно крепким, чтобы на нём строить.
Была ли эта статья полезной?

Alexis
Инженер ИИИнженер ИИ из Лозанны, сочетающий глубину исследований с практическими инновациями. Делит время между архитектурами моделей и альпийскими вершинами.
Похожие статьи
Продолжите изучение с этими статьями

MiniMax Hailuo 02: Бюджетная модель видеогенерации из Китая конкурирует с гигантами
Hailuo 02 от MiniMax генерирует видео конкурентного качества за небольшую часть стоимости, с 10 видео за цену одного клипа Veo 3. Вот что делает этого китайского претендента достойным внимания.

Kandinsky 5.0: Российский ответ в области открытой генерации видео с помощью ИИ
Kandinsky 5.0 обеспечивает генерацию 10-секундного видео на потребительских GPU с лицензией Apache 2.0. Мы рассмотрим, как механизмы NABLA attention и flow matching делают это возможным.

ИИ-видео в 2025 году: Год, когда всё изменилось
От Sora 2 до нативного звука, от миллиардных сделок Disney до команд из 100 человек, побеждающих гигантов с триллионной капитализацией, 2025 стал годом, когда ИИ-видео стало реальностью. Вот что произошло и что это значит.