LeRobot documentation

Simulação: local ou servida

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.7.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Simulação: local ou servida

Um ambiente simulado pode ser controlado de duas maneiras:

  • como um env em lote (--env.*): muitos ambientes para uma única tarefa, avançados juntos por cada chamada de step(). O lerobot-eval e a avaliação durante o treinamento usam esse modo.
  • como um robô simulado (--robot.type=sim): um ambiente atrás da interface Robot, substituível por hardware real. lerobot-rollout, lerobot-record, lerobot-teleoperate e lerobot-replay o utilizam.

Executa localmente, por meio da API de ambiente, ou servido por lerobot-env-server, geralmente em sua própria imagem Docker, para que as dependências do simulador nunca se encontrem com as da política. Definir um endpoint seleciona a execução servida; ambos os caminhos expõem as mesmas observações canônicas (imagens HWC uint8, estado float32 plano), fins de episódio e convenções de controle.

O código mantém três camadas separadas:

  • um env (lerobot.envs, --env.type) é o que um comando do LeRobot executa, configurado por um EnvConfig. Nem todo env é um simulador: gym_manipulator controla um robô real.
  • a sim (lerobot.sim) é o simulador por trás de um ambiente simulado: um SimConfig que nomeia sua integração, executado por LocalVectorEnv, sem torch.
  • o env server (lerobot.env_server) serve uma simulação; RemoteVectorEnv a controla com a mesma API de LocalVectorEnv.

Avaliar um checkpoint

Localmente, com o simulador instalado ao lado do LeRobot (veja 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_libero

Servido: inicie o servidor com o mesmo ambiente (veja Servir um ambiente) e adicione seu endpoint:

lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true
lerobot-eval ... --env.server.endpoint=tcp/127.0.0.1:7448

Todas as opções do servidor estão sob --env.server.*, e nenhuma se aplica a uma execução local. O cliente solicita o deployment nomeado conforme --env.type, como as configurações do servidor o nomeiam; passe --env.server.deployment para outro. Um endpoint ou deployment incorreto falha dentro de --env.server.handshake_timeout_s (10 s) e indica o que o endpoint serve. Contra um servidor protegido com TLS, passe seu arquivo Zenoh JSON5 com --env.server.zenoh_config_path, como para inferência remota. O servidor deve executar o ambiente descrito pelo comando: o mesmo type, task, convenções de controle e corpo simulado (robot_type), ou a avaliação se recusa a iniciar e lista as diferenças. Outras opções que diferem (resolução, comprimento do episódio) são registradas como avisos.

Os nomes das observações vêm do ambiente (observation.images.<camera>, observation.state). Quando um checkpoint foi treinado com outros nomes de câmeras, mapeie-os com --rename_map, como para qualquer robô, e preserve a identidade de cada câmera, mesmo quando várias têm o mesmo formato. Câmeras de preenchimento (empty_cameras) são uma configuração de política salva com o checkpoint; substitua-a com --policy.empty_cameras apenas quando necessário.

Antes do primeiro passo, cada checkpoint de entrada deve existir no ambiente após a renomeação, com dimensões de estado e ação compatíveis e o mesmo número de canais RGB. A altura e a largura da imagem podem diferir: o pré-processamento da política é responsável pelo redimensionamento. As convenções do controlador (ações delta versus absolutas, formato de rotação) não são verificadas; utilize um checkpoint treinado com a convenção do ambiente.

Cada step() avança uma vez todos os ambientes não finalizados no lote. Um ambiente que termina mantém sua observação terminal até o próximo reset; avançar os outros nunca o reinicia. Com --eval.use_async_envs=true (o padrão), cada ambiente é executado em seu próprio processo de worker, localmente ou no servidor, e o lote avança em paralelo. Um servidor aceita até max_envs ambientes por lote (32 por padrão). --env.server.encoding=jpeg (ou --robot.env.server.encoding=jpeg, com --env.server.jpeg_quality, 90 por padrão) envia os quadros de câmera servidos como JPEG: respostas menores para um servidor remoto e lotes maiores, ao custo de tempo de codificação e quadros com perda. No localhost, quadros brutos são mais rápidos. Uma resposta carrega os quadros de todos os ambientes no lote e deve caber em max_payload_bytes (32 MiB por padrão) em ambas as extremidades, ou o servidor recusa o lote quando ele é aberto. Para lotes grandes ou câmeras de alta resolução, aumente-o no servidor (max_payload_bytes na seção zenoh do YAML, ao lado de listen_endpoints) e no cliente (--env.server.max_payload_bytes, ou --robot.env.server.max_payload_bytes).

Executar um robô de simulação

O mesmo ambiente como um ambiente em lote e como um robô de simulação:

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 ...

Por exemplo:

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.* aceita as mesmas opções de --env.* na avaliação. --robot.task_id seleciona a única tarefa que o robô executa, enquanto a avaliação executa todas as tarefas da suíte ou aquelas em --env.task_ids. Os ambientes do EnvHub são --robot.env.type=envhub --robot.env.hub_path=<user/repo> --robot.env.trust_remote_code=true.
  • Algumas políticas exigem os processadores do ambiente (XVLA e Cosmos3 no LIBERO, Isaac Lab Arena). O lerobot-eval os aplica, assim como um robô de simulação com --inference.type=sync. A inferência remota não os aplica, portanto recusa esse checkpoint na inicialização.
  • --robot.env.server.endpoint=tcp/... executa o ambiente em um servidor de ambiente, assim como --env.server.endpoint faz para um ambiente em lote. O robô verifica se o servidor executa esse ambiente.
  • Cada send_action() avança o ambiente exatamente uma vez. Leitura de observações, inferência da política e espera não avançam a simulação; o loop de controle existente é responsável pelo ritmo em tempo real.
  • --fps deve ser igual à taxa de controle do ambiente, dividida por --interpolation_multiplier ao interpolar, pois cada comando avança o ambiente uma vez. Ao gravar, --dataset.fps deve ser igual a --fps. Caso contrário, o rollout se recusa a iniciar.

Um robô de simulação é um robô: substitua --robot.type=sim --robot.env.* pelos parâmetros --robot.* do seguidor real, e o restante permanece inalterado. Um teleoperador o controla da mesma forma que controla o seguidor real (--teleop.type=so101_leader para um gêmeo SO-101), quando o ambiente declara os nomes e as unidades das ações do seguidor; uma incompatibilidade é reportada na primeira ação. O lerobot-record armazena o corpo declarado pelo ambiente como o robot_type do conjunto de dados (panda para LIBERO), ou sim_robot quando nenhum é declarado.

Os episódios gravados seguem os do ambiente. lerobot-record e a estratégia de rollout episódico reiniciam o ambiente simulado no início de cada episódio e o encerram quando o episódio do ambiente termina (sucesso, terminação ou seu limite de passos) ou quando sua duração se esgota, o que ocorrer primeiro. Cada episódio gravado é, portanto, um episódio simulado, a partir de seu estado inicial. Nada precisa ser reiniciado manualmente, então pule a fase de reset entre episódios com --dataset.reset_time_s=0 e, com a estratégia de rollout episódico, também passe --strategy.reset_to_initial_position=false. Quando um episódio termina, o robô para: ele ignora ações e mantém seu estado final, e latest mantém a recompensa final, a terminação e o sucesso. A teleoperação e a estratégia de rollout base então iniciam um novo episódio (a estratégia também reinicia a política), e o replay para. As estratégias sentry, highlight e DAgger ainda não suportam robôs simulados, pois gravam por tempo ou sob demanda, em vez de por episódio; use a estratégia episódica para gravar. Robôs reais não são afetados: seus episódios são cronometrados e sua cena é reiniciada manualmente. Para taxas de sucesso, avalie com lerobot-eval e um ambiente em lote.

Os recursos da câmera do robô usam os mesmos nomes observation.images.<camera> que a gravação em hardware real. Uma única câmera sem nome é observation.images.image. A avaliação em lote mantém as próprias chaves do ambiente, como observation.image para uma única câmera; ao implantar um checkpoint com esse nome por meio de SimRobot, use --rename_map='{"observation.images.image": "observation.image"}'.

Para inferência remota, mantenha as mesmas opções --robot.* e substitua as opções locais de política e inferência por:

--inference.type=remote \
--inference.endpoint=tcp/127.0.0.1:7447 \
--inference.deployment=libero \
--inference.semantics=libero-delta-v1

Inicie o servidor de política separadamente usando remote inference setup. Seu schema deve corresponder às observações do robô após --rename_map. Omita --policy.path do comando de rollout, pois o servidor de política carrega o checkpoint. Para RTC local, use --inference.type=rtc com as configurações de RTC da política.

Quando a política está atrasada, manter um robô de simulação não avança a física. Falhas no simulador propagam-se para o encerramento do rollout.

Servir um ambiente

A partir de um checkout da fonte do LeRobot (a imagem é construída a partir dele), execute a partir da raiz do repositório:

lerobot-env-server --config_path=docker/sim/configs/libero.yaml --docker=true

--docker=true usa docker/sim/compose.server.yaml, seleciona a imagem a partir de sim.type, monta o YAML efetivo e executa o container na rede do host, de modo que o servidor escuta em localhost:7448, a menos que --zenoh.listen_endpoints indique o contrário. Troque o YAML para selecionar outro simulador. A taxa de controle, a convenção de ação, os nomes dos componentes e o tipo de robô de cada simulador vêm do conventions() da sua integração, de modo que um YAML apenas nomeia a tarefa e as opções do simulador.

No que diz respeito ao lerobot-policy-server, cada campo YAML aceita uma substituição aninhada na linha de comando, e o arquivo permanece inalterado. Um valor de dicionário como sim.kwargs é mesclado ao do 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}}'

A configuração efetiva é mantida em $HF_LEROBOT_HOME/sim, de modo que um container reiniciado a encontre. Alterar a configuração recria o servidor e encerra as sessões ativas. A imagem é construída quando ausente; adicione --build=true para reconstruí-la após alterar o simulador ou o código-fonte do LeRobot, ou --stop=true para desligar o servidor. O container requer acesso à GPU do Docker para renderização EGL. Os repositórios do EnvHub são servidos com --envhub=<user/repo>; consulte EnvHub e o servidor do simulador.

Se um simulador que renderiza com Vulkan (Isaac Sim, ou ManiSkill/SAPIEN como em RoboMME, cuja imagem inclui seu próprio arquivo Vulkan) falhar no contêiner com vkCreateInstance failed ou ERROR_INCOMPATIBLE_DRIVER enquanto funciona fora do Docker, o contêiner possui as bibliotecas do driver da NVIDIA, mas não os arquivos de loader que apontam para elas (/usr/share/vulkan/icd.d/nvidia_icd.json, /usr/share/glvnd/egl_vendor.d/10_nvidia.json). O modo padrão do NVIDIA Container Toolkit, usado por gpus: all, pode não montá-los; seu modo CDI sim. Solicite a GPU através do CDI (--device nvidia.com/gpu=all para docker run, devices: [nvidia.com/gpu=all] no lugar de gpus: all em docker/sim/compose.server.yaml), ou adicione os dois arquivos à imagem.

Sem --docker=true, o mesmo comando executa o servidor no ambiente atual: instala as dependências nativas do simulador em um ambiente isolado, instala o LeRobot com --no-deps e instala docker/sim/requirements.txt. De qualquer forma, ele escuta em localhost; para aceitar outras máquinas, passe o endereço da interface de rede que elas alcançam, como em --zenoh.listen_endpoints='[tcp/192.168.1.20:7448]', e adicione TLS e controle de acesso com um zenoh.config_file no YAML.

As imagens de runtime do LIBERO usam arquivos de estado inicial convertidos do NumPy. A compilação da imagem converte os ativos confiáveis de upstream com scripts/ci/convert_libero_init_states.py; o servidor rejeita arquivos convertidos ausentes. O RoboTwin e o RoboMME exigem seu próprio torch para planejamento nativo e ManiSkill, respectivamente; suas instalações de torch são isoladas do ambiente de policy.

As solicitações do servidor nunca são repetidas. Após um tempo limite ambíguo, o cliente falha; feche-o e abra uma nova sessão.

Adicionar um benchmark

Consulte Adicionando um benchmark para módulos de simulador, convenções, imagens e integração de CI.

Update on GitHub