LeRobot documentation
Симуляция: локальная или через сервер
Симуляция: локальная или через сервер
Симулированная среда может управляться двумя способами:
- в виде batched env (
--env.*): множество сред для одной задачи, которые обрабатываются совместно при каждом вызовеstep().lerobot-evalи оценка во время обучения используют именно этот режим. - в качестве симуляционного робота (
--robot.type=sim): одна среда за интерфейсомRobot, заменяемая на реальное оборудование.lerobot-rollout,lerobot-record,lerobot-teleoperateиlerobot-replayиспользуют его.
Запуск выполняется локально, через API окружения, либо в режиме сервиса с помощью lerobot-env-server, как правило, в отдельном Docker-образе, чтобы зависимости симулятора не пересекались с зависимостями политики. Установка параметра endpoint выбирает режим сервиса; оба пути предоставляют одинаковые канонические наблюдения (изображения HWC uint8, плоское состояние float32), окончания эпизодов и соглашения по управлению.
Код разделяет три уровня:
- env (
lerobot.envs,--env.type) — это среда, в которой выполняется команда LeRobot, настраиваемая черезEnvConfig. Не каждая среда является симулятором:gym_manipulatorуправляет реальным роботом. - sim (
lerobot.sim) — это симулятор, лежащий в основе симулированного окружения:SimConfig, задающий его интеграцию, шаг которого выполняетсяLocalVectorEnvбез использования torch. - env server (
lerobot.env_server) обслуживает симуляцию;RemoteVectorEnvуправляет ею с тем же API, что иLocalVectorEnv.
Оценка контрольной точки
Локально, с установленным рядом с LeRobot симулятором (см. LIBERO):
lerobot-eval \
--policy.path=lerobot/smolvla_libero \
--policy.pretrained_revision=a24f1f380461b665158d52acd140152c79e8b36d \
--policy.device=cuda \
--env.type=libero --env.task=libero_spatial --env.task_ids='[0]' \
--rename_map='{"observation.images.image": "observation.images.camera1", "observation.images.image2": "observation.images.camera2"}' \
--eval.n_episodes=1 --eval.batch_size=1 \
--output_dir=outputs/eval_liberoServed: запустите сервер с тем же окружением (см. Развертывание окружения) и добавьте его конечную точку:
lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true
lerobot-eval ... --env.server.endpoint=tcp/127.0.0.1:7448Все параметры сервера находятся в --env.server.* и не применяются к локальному запуску. Клиент запрашивает развёртывание, имя которого соответствует значению --env.type, как оно указано в конфигурации сервера; для другого развёртывания передайте --env.server.deployment. Неправильный конечный пункт или развёртывание приводит к сбою в пределах --env.server.handshake_timeout_s (10 с) и указывает, что именно обслуживает данный конечный пункт. Для сервера с защищённым TLS-соединением передайте его файл Zenoh JSON5 с помощью --env.server.zenoh_config_path, как при удалённом выводе. Сервер должен запускать окружение, описанное командой: тот же тип, задача, соглашения управления и симулируемое тело (robot_type), иначе оценка откажется запускаться и перечислит различия. Другие отличающиеся параметры (разрешение, длина эпизода) логируются как предупреждения.
Имена наблюдений задаются средой (observation.images.<camera>, observation.state). Если чекпоинт обучался с другими именами камер, сопоставьте их с помощью --rename_map, как и для любого робота, сохраняя идентичность каждой камеры, даже если у нескольких одинаковая форма. Заполняющие камеры (empty_cameras) — это настройка политики, сохраняемая вместе с чекпоинтом; переопределяйте её с помощью --policy.empty_cameras только при необходимости.
Перед первым шагом каждый входной чекпоинт должен существовать в среде после переименования, с совпадающими размерностями состояния и действия, а также количеством каналов RGB. Высота и ширина изображения могут отличаться: за масштабирование отвечает предобработка политики. Соглашения контроллера (дельта или абсолютные действия, формат вращения) не проверяются; используйте чекпоинт, обученный на соглашениях среды.
Каждый вызов step() продвигает на один шаг каждую незавершённую среду в батче. Завершённая среда сохраняет своё терминальное наблюдение до следующего сброса; шаги остальных сред не перезапускают её. При --eval.use_async_envs=true (значение по умолчанию) каждая среда работает в собственном рабочем процессе, локально или на сервере, и батч шагает параллельно. Сервер принимает не более max_envs сред на батч (по умолчанию 32). Параметр --env.server.encoding=jpeg (или --robot.env.server.encoding=jpeg, вместе с --env.server.jpeg_quality, по умолчанию 90) отправляет кадры камер в формате JPEG: это уменьшает размер ответов для удалённого сервера и позволяет использовать более крупные батчи, ценой времени на кодирование и потери качества. На localhost сырые кадры обрабатываются быстрее. Ответ содержит кадры всех сред в батче и должен помещаться в max_payload_bytes (по умолчанию 32 МиБ) на обоих концах, иначе сервер отклоняет батч при его открытии. Для крупных батчей или камер высокого разрешения увеличьте это значение на сервере (max_payload_bytes в разделе zenoh YAML-файла, рядом с listen_endpoints) и на клиенте (--env.server.max_payload_bytes, или --robot.env.server.max_payload_bytes).
Запустите симулированного робота
Та же среда, что и в пакетной среде и в симулированном роботе:
lerobot-eval --env.type=libero --env.task=libero_spatial --env.task_ids='[0]' ...
lerobot-rollout --robot.type=sim --robot.env.type=libero --robot.env.task=libero_spatial --robot.task_id=0 ...Например:
lerobot-rollout \
--robot.type=sim --robot.env.type=libero --robot.env.task=libero_spatial --robot.task_id=0 \
--task="pick up the black bowl between the plate and the ramekin and place it on the plate" \
--policy.path=lerobot/smolvla_libero \
--policy.pretrained_revision=a24f1f380461b665158d52acd140152c79e8b36d \
--rename_map='{"observation.images.image": "observation.images.camera1", "observation.images.image2": "observation.images.camera2"}' \
--device=cuda --fps=20 --inference.type=sync \
--display_data=true --display_mode=rerun \
--return_to_initial_position=false --play_sounds=false--robot.env.*принимает те же параметры, что и--env.*при оценке.--robot.task_idвыбирает одну задачу, которую выполняет робот, тогда как при оценке выполняется каждая задача набора или те, что указаны в--env.task_ids. Среда EnvHub настраивается так:--robot.env.type=envhub --robot.env.hub_path=<user/repo> --robot.env.trust_remote_code=true.- Некоторые политики требуют процессоров среды (XVLA и Cosmos3 на LIBERO, Isaac Lab Arena).
lerobot-evalприменяет их, как и симулированный робот с--inference.type=sync. Удалённый инференс этого не делает, поэтому при запуске он отклоняет такой чекпоинт. --robot.env.server.endpoint=tcp/...запускает среду на сервере сред, как это делает--env.server.endpointдля пакетной среды. Робот проверяет, что сервер выполняет именно эту среду.- Каждый вызов
send_action()продвигает среду ровно на один шаг. Чтение наблюдений, инференс политики и ожидание не продвигают симуляцию; существующий цикл управления отвечает за тактирование по реальному времени. --fpsдолжен быть равен частоте управления средой, делённой на--interpolation_multiplierпри интерполяции, поскольку каждая команда продвигает среду на один шаг. При записи--dataset.fpsдолжен быть равен--fps. В противном случае запуск rollout будет отклонён.
Симуляционный робот — это тоже робот: замените --robot.type=sim --robot.env.* на --robot.* реального ведомого робота, и всё остальное останется без изменений. Телеоператор управляет им так же, как он управляет реальным ведомым роботом (--teleop.type=so101_leader для пары SO-101), когда среда объявляет имена и единицы действий ведомого робота; при несоответствии ошибка сообщается при первом действии. lerobot-record сохраняет тело, объявленное средой, как robot_type набора данных (panda для LIBERO), или sim_robot, если среда ничего не объявляет.
Записываемые эпизоды следуют за эпизодами среды. lerobot-record и стратегия эпизодического развёртывания перезапускают симулированную среду в начале каждого эпизода и завершают её, когда эпизод среды завершается (успех, терминация или достижение лимита шагов) или когда истёк его срок, что наступит раньше. Таким образом, каждый записанный эпизод представляет собой один симулированный эпизод, начиная с его начального состояния. Никакой ручной сброс не требуется, поэтому пропустите фазу сброса между эпизодами с помощью --dataset.reset_time_s=0, а при использовании стратегии эпизодического развёртывания также передайте --strategy.reset_to_initial_position=false. Когда эпизод завершается, робот останавливается: он игнорирует действия и сохраняет своё конечное состояние, а latest сохраняет конечное вознаграждение, терминацию и успех. Затем телеуправление и базовая стратегия развёртывания начинают новый эпизод (стратегия также сбрасывает политику), а воспроизведение останавливается. Стратегии sentry, highlight и DAgger пока не поддерживают симулированных роботов, поскольку они записывают данные по времени или по запросу, а не по эпизодам; для записи используйте стратегию эпизодического развёртывания. Реальные роботы не затрагиваются: их эпизоды ограничены по времени, а их сцена сбрасывается вручную. Для оценки показателей успеха используйте lerobot-eval и пакетную среду.
Функции камеры робота используют те же имена observation.images.<camera>, что и запись с реального оборудования. Для одной камеры без имени используется observation.images.image. При пакетной оценке сохраняются собственные ключи среды, например observation.image для одной камеры; при развёртывании контрольной точки с таким именем через SimRobot используйте --rename_map='{"observation.images.image": "observation.image"}'.
Для удалённого вывода сохраняйте те же параметры --robot.* и замените локальные параметры политики и вывода на:
--inference.type=remote \ --inference.endpoint=tcp/127.0.0.1:7447 \ --inference.deployment=libero \ --inference.semantics=libero-delta-v1
Запустите сервер политики отдельно с помощью настройки удалённого вывода. Его схема должна соответствовать наблюдениям робота после применения --rename_map. Опустите --policy.path из команды rollout, так как сервер политики загружает контрольную точку. Для локального RTC используйте --inference.type=rtc с настройками RTC политики.
Если политика опаздывает, удержание симуляционного робота не продвигает физику вперёд. Сбои симулятора приводят к остановке rollout.
Запуск среды
Из исходного кода LeRobot (из него собирается образ) выполните из корня репозитория:
lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true--docker=true использует docker/sim/compose.server.yaml, выбирает образ на основе sim.type, монтирует эффективный YAML и запускает контейнер в сети хоста, поэтому сервер слушает localhost:7448, если --zenoh.listen_endpoints не указывает иное. Замените YAML, чтобы выбрать другой симулятор. Частота управления, соглашения об действиях, имена компонентов и тип робота для каждого симулятора определяются методом conventions() его интеграции, поэтому в YAML указываются только задача и параметры симулятора.
Что касается lerobot-policy-server, каждое поле YAML принимает вложенное переопределение из командной строки, при этом файл остаётся неизменным. Значение словаря, например sim.kwargs, объединяется с соответствующим значением в YAML:
lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true \
--sim.task=libero_goal \
--sim.kwargs='{gym_kwargs: {observation_height: 256, observation_width: 256}}'Эффективная конфигурация сохраняется в $HF_LEROBOT_HOME/sim, поэтому перезапущенный контейнер находит её. Переключение конфигурации пересоздаёт сервер и завершает активные сессии. Образ собирается при отсутствии; добавьте --build=true, чтобы пересобрать его после изменения симулятора или исходного кода LeRobot, или --stop=true, чтобы остановить сервер. Контейнеру требуется доступ Docker к GPU для рендеринга EGL. Репозитории EnvHub обслуживаются с помощью --envhub=<user/repo>; см. EnvHub и сервер симулятора.
Если симулятор, использующий Vulkan для рендеринга (Isaac Sim или ManiSkill/SAPIEN, как в RoboMME, чей образ содержит собственный файл Vulkan), завершается с ошибкой
vkCreateInstance failedилиERROR_INCOMPATIBLE_DRIVERвнутри контейнера, хотя за его пределами работает корректно, это означает, что в контейнере присутствуют библиотеки драйвера NVIDIA, но отсутствуют файлы загрузчика, указывающие на них (/usr/share/vulkan/icd.d/nvidia_icd.json,/usr/share/glvnd/egl_vendor.d/10_nvidia.json). Режим по умолчанию в NVIDIA Container Toolkit, используемый приgpus: all, может не монтировать эти файлы; режим CDI делает это. Запросите GPU через CDI (--device nvidia.com/gpu=allдляdocker run,devices: [nvidia.com/gpu=all]вместоgpus: allвdocker/sim/compose.server.yaml) или добавьте эти два файла в образ.
Без --docker=true та же команда запускает сервер в текущей среде: устанавливает нативные зависимости симулятора в изолированную среду, устанавливает LeRobot с --no-deps и устанавливает docker/sim/requirements.txt. В любом случае сервер слушает localhost; чтобы принимать подключения с других машин, передайте адрес сетевого интерфейса, по которому они могут подключиться, как в --zenoh.listen_endpoints='[tcp/192.168.1.20:7448]', и добавьте TLS и управление доступом с помощью zenoh.config_file в YAML.
Образы среды выполнения LIBERO используют преобразованные файлы начального состояния NumPy. Сборка образа преобразует доверенные исходные активы с помощью scripts/ci/convert_libero_init_states.py; сервер отклоняет отсутствующие преобразованные файлы. RoboTwin и RoboMME требуют собственных установок torch для нативного планирования и ManiSkill соответственно; их установки torch изолированы от окружения политики.
Запросы к серверу никогда не повторяются. После неоднозначного таймаута клиент завершает работу с ошибкой; закройте его и откройте новую сессию.
Добавить бенчмарк
См. Добавление бенчмарка для информации о модулях симулятора, соглашениях, изображениях и интеграции с CI.
Update on GitHub