Один текст — любые скелеты. Как UniMate анимирует собаку, дракона и робота одинаково
Представьте, что у вас есть сцена с десятком разных существ: двуногий персонаж, четвероногая собака, дракон, змея, робот на сервоприводах. И вам нужно, чтобы все они пришли в движение по текстовому описанию. Классический путь такой: под каждое существо строите скелет, размечаете кости, учите отдельную модель или гоняете долгую оптимизацию под конкретный риг. Звучит как недели работы, правда?
Группа исследователей из Princeton, UC Berkeley, MIT и NTU пошла другим путём. Их проект UniMate, принятый на SIGGRAPH Asia 2026, обучает одну модель, которая генерирует движение для произвольных скелетов по тексту — без переобучения под каждый новый риг и без оптимизации во время инференса. Генерирует в реальном времени. Вот это уже интересно.

Что вообще происходит
Стандартная проблема text-to-motion в том, что движения жёстко привязаны к топологии скелета. Модель, натренированная на человеческих mocap-данных, просто не знает, что делать с шестиногим насекомым или морским существом. Разные скелеты — разные наборы костей, разная иерархия, разное число суставов.
UniMate решает это через каноникализацию. Авторы собрали UniML3D — датасет из 13 006 текстово-связанных motion-последовательностей, охватывающих двуногих, четвероногих, птиц, морских существ, насекомых, змей и даже артикулированные жёсткие объекты. Все они приведены к единому каноническому виду, и именно это единство позволяет одной модели работать поверх всей этой мешанины скелетов.

Ключевые возможности
Текст в движение за один прогон
На вход подаёте ригнутый 3D-ассет и текстовый промпт, на выходе — артикулированное движение. Никакого per-skeleton fine-tuning. Пример тестового кейса выглядит буднично:
{
"Dog-walk": "a dog walks forward at a steady pace",
"Dragon-takeoff": "a dragon flaps its wings and takes off"
}
Дальше одна команда — и на выходе получаете .npy с фичами движения плюс отрендеренный MP4 со скелетом:
python -m unimate.inference.sample \
--exp_dir outputs/uniml3d_60frames_graph_adaln \
--test_cases_json test_cases.json \
--num_repetitions 3
Три задачи без дообучения
Самое любопытное: та же обученная модель делает ещё три вещи, вообще не требуя отдельного тюнинга. Везде применяется приём replacement-style sampling — часть движения пришпилена к известному сигналу, а flow ODE разглаживает остальное на каждом шаге. То есть ограничение держится точно, а не «убеждается» лоссом.
Motion in-betweening. Задаёте ключевые кадры, получаете переходы между ними:
KEEP_FRAMES="0,-1" bash scripts/run_sample_motion_inbetween.sh \
outputs/uniml3d_60frames_graph_adaln cases.json
Text-guided motion editing. Фиксируете выбранные суставы на их настоящем движении, меняете промпт — и перегенерируете всё остальное. Скажем, хочется, чтобы робот шёл вперёд, но торс и шея остались как были:
KEEP_JOINTS="Hips,Spine,Neck,Head" bash scripts/run_sample_motion_edit.sh \
outputs/uniml3d_60frames_graph_adaln cases.json
Motion expansion. Сцепляете несколько промптов в одно длинное движение. Первый сегмент генерится свободно, каждый следующий пришпиливает первые кадры к хвосту предыдущего, а на стыке сегменты сшиваются:
EXPAND_OVERLAP=10 bash scripts/run_sample_motion_expand.sh \
outputs/uniml3d_60frames_graph_adaln cases.json

Анимировать оригинальный меш тоже можно: файлы .npy скармливаете пятой стадии пайплайна, и он отдаёт анимированный GLB вместе с FBX.
Как это устроено внутри
Обучение построено на flow matching: сеть предсказывает скорость линейного интерполянта между шумом и данными, лосс — маскированный L2 плюс два вспомогательных члена, посчитанных на восстановленном чистом движении. Один отвечает за геодезические вращения, второй — за гладкость скоростей.
Кондиционирование ронять не обязательно: с вероятностью model.cond_mask_prob условие отбрасывается, поэтому одни и те же веса обслуживают и условную, и безусловную ветки, которые потом интерполирует classifier-free guidance.
Авторы дают два варианта внимания на выбор. Первый факторизует внимание на пространственный проход (по кадру) и временной (по суставу) с bias'ами по графовому расстоянию, типу ребра и глубине. Второй — один cross-attention по расплющенным токенам «сустав × время». Оси независимы друг от друга, так что комбинаций на деле четыре, хотя в конфигах поставляются два варианта, которые сравнивает статья.
Текстовый энкодер по умолчанию — google/flan-t5-base. Его эмбеддинги можно посчитать заранее, чтобы не тащить модель в каждый прогон:
python -m unimate.tools.precompute_text_emb --config configs/uniml3d_60frames_graph_adaln.json
Отдельно заслуживает упоминания сэмплер: при включённом балансировании тип с n клипами берётся пропорционально n^(1-sampler_alpha). При sampler_alpha = 0.5 вид со 100 клипами встречается в десять раз чаще вида с одним клипом, а не в сто. Логично — иначе редкие существа просто утонут.
На что наступить можно
Авторы честны: часть ригов и клипов в Objaverse-XL бракованные — лежачие или перевёрнутые rest pose, склеенные из разных действий клипы. Такие данные роняют или дестабилизируют обучение, и одиночные всплески лоса в трейне обычно означают плохие данные, а не проблему оптимизации. Лечится просто: сначала тренируете на Mixamo и Truebones, убеждаетесь, что всё здорово, а потом находите проблемные объекты глазами или автоматически и заносите в skip-листы.
Ещё момент лицензий. Код под MIT, но данные живут по своим правилам. Ассеты Mixamo — по Adobe, Objaverse-XL — по лицензии каждого объекта, а движения Truebones ZOO — коммерческий пакет, который нельзя перераспространять: покупайте напрямую у Truebones, пайплайн ест стоковую раскладку папки как есть.
И про ожидания. UniMate сами авторы называют раннÝим шагом к text-to-animation для любого скелета. Многие движения и скелеты всё ещё проваливаются. Направление для улучшения они видят в масштабировании данных — дистилляции из агентов или генерации из видео. Если наткнётесь на фейл, просят открыть issue: это помогает им чинить.
Кому это нужно
Если вы работаете с анимацией 3D-персонажей, генерируете контент для игр или VR, экспериментируете с генеративными motion-моделями — тут есть что посмотреть. Проект особенно интересен тем, кто устал плодить отдельные модели под каждый риг и хочет одну сеть для всей разношёрстной фауны. Уже 1049 звёзд и почти сотня форков, что для научного репозитория довольно живо.
С чего начать? Разверните окружение из requirements.txt, качните preview-чекпоинты с HuggingFace, посмотрите интерактивную демку в браузере, а потом уже беритесь за свой риг. Учтите, что обрабатывать новые out-of-distribution скелеты авторы обещают отдельным пайплайном — на момент релиза он ещё в TODO. Так что для нестандартных скелетов придётся немного подождать или копаться самому.
В целом это крепкая исследовательская работа с открытым кодом и данными, где границы применимости описаны честно. Редкость. Если ваша задача как-то пересекается с анимацией скелетов, стоит потратить вечер на эксперимент.
