
Привет, Хабр! Меня зовут Лёша Лещанкин, я руковожу проектом Humanoids в Яндексе. В начале 2025 года мы запустили это направление при поддержке фонда технологических инициатив компании — Yet Another Tech Fund, созданного специально для реализации новаторских идей сотрудников. Наша цель — создать гуманоидных роботов, которые смогут уверенно и безопасно работать рядом с людьми в самых разных условиях: от логистики и промышленности до сферы обслуживания.
В рамках нашего проекта мы тестируем разные RL‑модели. И сегодня расскажу об одном из методов, который позволил нам перейти от «робот дёргается и падает» к «робот ходит плавно 500 шагов подряд» — Lipschitz‑Constrained reinforcement learning.
Зачем вообще RL в управлении гуманоидом
Классические подходы к управлению двуногими роботами требуют ручной настройки сотен параметров. Мы учим робота методом проб и ошибок в симуляции, но с важным отличием — используем математические ограничения для безопасности.

В итоге RL даёт адаптивность, а значит, быстрее выводит фичи (доставка, сопровождение, инспекция) в прод.
В чём состоят ключевые преимущества RL‑подхода:
робот сам находит оптимальную походку под свою механику;
он адаптируется к разным поверхностям без перепрограммирования;
обеспечивается устойчивость к возмущениям и непредвиденным ситуациям;
есть возможность переноса навыков между разными моделями роботов.
Однако когда ты запускаешь симулированную RL‑политику на настоящем гуманоиде — ты почти всегда видишь это: робот начинает «дёргаться», рывками размахивает ногами и в лучшем случае просто падает. Всё было идеально в симуляции, но моторы не выдержали реальности.
Это классическая проблема «симуляция → реальный мир». Несмотря на обширную доменную рандомизацию (вариации масс, трения, задержек и добавление сенсорного шума), оптимизатор всё равно вырабатывает «жёсткую» bang‑bang‑политику: она трактует даже крошечный сенсорный шум как принципиально новое состояние и тут же перестраивает цикл шага. На реальном роботе это приводит к резким, нестабильным переходам, а пиковые моменты, которые казались оптимальными в симуляции, упираются в реальные ограничения приводов. Главное узкое место переноса sim → real не в самом шуме, а в чрезмерной чувствительности политики к нему и в игнорировании аппаратных лимитов. Результат — непереносимость, нестабильность и физическая невозможность выполнения движений.
В недавней статье Learning Smooth Humanoid Locomotion through Lipschitz‑Constrained Policies (ICRA 2025) авторы предложили элегантное решение: наказывать нейросеть за «резкие» действия, измеряя, насколько она чувствительна к входу. Метод прост, дифференцируем и прекрасно переносится на реальных роботов.
От симуляции к железу
Представьте: вы обучили идеальную политику управления роботом в симуляторе. В Isaac Sim ваш гуманоид грациозно ходит, бегает, даже танцует. Переносите на реальное железо и... робот дёргается и падает через 10 секунд.
Почему так происходит?
В реальности сенсоры шумят. IMU дребезжит на ±2%, энкодеры дают погрешность, Wi‑Fi вносит задержки. И вот маленький шум в 0,1° наклона превращается в команду мотору «ДЁРНИ НА 50 Нм!» — и робот падает.
Решение: учим нейросеть быть нечувствительной к шуму. Классический подход — применить фильтры Калмана и сглаживание. Работает, но требует много параметров и настройки под каждого робота. Мы же пошли другим путём: учим нейросеть с самого начала плавно реагировать на входы.
Условие Липшица для политики робота:
Простыми словами, если состояние робота изменилось чуть‑чуть, то и действия должны измениться чуть‑чуть. Никаких резких скачков! То есть если шум IMU — 2°, то изменение команды мотору составит максимум 1° (а не 50°!), что даст в результате плавные, предсказуемые движения.
Для простоты понимания представьте два сценария:
Без ограничения (обычная нейросеть): Шум сенсора 1% → Команда мотору меняется на 50% → Робот дёргается
С Lipschitz constraint: Шум сенсора 1% → Команда мотору меняется максимум на 0,5% → Плавное движение
Это гарантирует, что малые изменения в сенсорах приводят к малым изменениям в командах моторам — критично для переноса на реальное железо.
Как это работает: градиент от градиента
Ключевая идея — добавить к обычной функции потерь RL специальный штраф за «резкость» политики:
# Псевдокод: основная логика метода
def lipschitz_constraint(policy, states, actions, lambda_gp):
# Включаем отслеживание градиентов для входов
states = states.requires_grad_(True)
# Прогоняем через политику
log_probs = policy.log_prob(actions, states)
# Ключевой момент: считаем градиент выхода по входу
input_gradients = compute_gradient(log_probs, states, keep_graph=True)
# Штраф = насколько резко меняется выход
penalty = lambda_gp * norm(input_gradients)
return penalty
# В training loop
rl_loss = compute_ppo_loss(...) # или любой другой RL-алгоритм
smooth_penalty = lipschitz_constraint(...)
total_loss = rl_loss + smooth_penalty
Почему это градиент от градиента? Ответ прост:
Первый градиент:
— насколько действия чувствительны к входам.
Второй градиент: при backprop мы считаем, как изменить веса сети, чтобы эта чувствительность уменьшилась.
Сначала мы считаем , а потом его градиент по всем весам сети, чтобы уменьшить чувствительность политики.
Мы буквально учим сеть быть менее «дёрганой». Условно, ты говоришь нейросети: «Я накажу тебя, если ты ведёшь себя слишком чувствительно к входам. Что нужно изменить в твоих весах, чтобы ты стала менее чувствительной?».
Что «под капотом»: классическая модель обучения с подкреплением
Мы используем базовый RL‑алгоритм — Proximal Policy Optimization (PPO). Это один из самых популярных алгоритмов RL благодаря его стабильности и хорошему балансу между исследованием и эксплуатацией.
Политика
Представлена нейросетью, параметризованной с помощью MLP (multilayer perceptron).
Вход: вектор наблюдений
, который включает:
фазу походки (синус и косинус);
команду на скорость
;
состояния робота
(позы, скорости суставов);
предыдущие действия
;
привилегированную информацию (масса, центр масс и т. д. — используется только на этапе тренировки).
Это позволяет обучать политику в симуляции с полным знанием динамики, а затем использовать её без дообучения на железе.
Выход политики
Предсказывает таргетные значения суставных углов (target joint positions).
Эти углы конвертируются в торки через стандартный PD‑контроллер (с фиксированными коэффициентами).
PPO-обучение
Оптимизация идёт по стандартной PPO‑цели:
К ней добавляют Lipschitz gradient penalty:
Обучение
В симуляции Isaac Gym, massive‑parallel, на тысячах копий среды (в нашем случае num_envs= 4096).
Sim2Real без fine‑tuning: политика одна и та же — сразу на железо.
Sim2Real Transfer
Используется ROA (Regularized Online Adaptation) — это дополнительная техника, основанная на teacher‑student и latent embedding. Но она не требуется для самого метода Lipschitz penalty, а, скорее, поддерживает robustness.
Практическая польза
Использование PPO даёт нам много преимуществ. Что касается робота, то он получает:
Устойчивость к шуму (Robustness ≈ Stability). Мелкие помехи в сенсорах не вызывают резких движений.
Безопасность. Нет внезапных рывков, которые могут сломать механику.
Энергоэффективность. Плавные движения потребляют меньше энергии.
Sim2Real Transfer. Поведение в симуляции близко к реальности. Липшиц‑штраф (grad penalty) сглаживает политику; в реальном мире она не завалит моторы пиками тока.
А относительно всего проекта — такие плюсы:
Платформа ходьбы стабильна. Можно подключать высший уровень задач ‑ перенос груза, лестницы, протягивание руки.
Перенос на железо. Первые стенд‑тесты показывают, что падений нет.
Экономия на тюнинге. Вместо недель ручных коэффициентов мы меняем одну строку с λ и перезапускаем ран.
Наши результаты
После 18 часов обучения на кластере мы получили такие результаты по ключевым метрикам:
Episode length выросла с 10 до 499 шагов — робот не падает почти 50 секунд!
Grad penalty loss: 11,83 — агрессивная регуляризация для safety.
Mean reward: 42,54 — нашли баланс между всеми целями.
Также в процессе обучения мы отслеживаем две ключевые метрики адаптации:
Adaptation/priv_reg_loss — показывает, насколько политика робота зависит от «привилегированной информации» (точные параметры симуляции, которые недоступны на реальном железе). Резкое падение на 2–4k шагах означает, что модель научилась полагаться только на реальные сенсоры.
Adaptation/hist_latent_loss — отражает качество предсказания скрытых состояний робота (скорости, ускорения) из истории наблюдений. Когда эта метрика падает, робот начинает точно оценивать свою динамику без прямых измерений.
Оба графика показывают классический паттерн: хаотичное начало → резкий прорыв → стабилизация. Это момент, когда нейросеть «понимает» задачу и переходит от случайных движений к осмысленной походке.


Видите резкое падение всех функций потерь? Это момент, когда робот научился ходить. А Lipschitz constraint обеспечил, чтобы походка сразу стала плавной.
Почему это работает zero-shot?
В отличие от политик, которые переобучаются под шумную симуляцию, LCP обучается быть устойчивой к флуктуациям входа с самого начала. Это означает, что нейросеть не «подстраивается» под точные значения наблюдений, а учится реагировать на диапазон состояний одинаково плавно. Это и делает возможным перенос на новое железо без fine‑tuning.
А что в итоге?
Мы проверили метод на двух реальных роботах: Fourier GR1 и Unitree H1. Сравнение с классическими методами (награды за плавность, low‑pass фильтры) показало, что LCP:
работает сразу на железе, без fine‑tuning;
даёт сопоставимую плавность движений;
избавляет от ручной настройки весов штрафов;
прост в реализации и добавляется в любую RL‑схему.

Заключение
Знаете, что самое крутое в работе с гуманоидами? Каждый день — это микс из математики, инженерии и чистой магии. Утром ты доказываешь «сходимость алгоритма», днём калибруешь сенсоры, а вечером смотришь, как железяка весом 50 кг делает первые шаги — и это твой код заставляет её двигаться.
Lipschitz‑Constrained Policies — это способ учить нейросети быть устойчивыми к реальному миру на уровне функции потерь, а не костылями после обучения. К слову, если вы работаете с роботами или любым Sim2Real Transfer, — попробуйте добавить этот constraint. Overhead небольшой, а выигрыш в стабильности огромный.
Мы сейчас на пороге запуска field tests на реальном железе. Страшно? Безумно. Но когда видишь, как робот, обученный в симуляции, делает первый шаг в реальном мире и не падает — это стоит всех ночей дебага.