LeRobot documentation
Simulação: local ou servida
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 destep(). Olerobot-evale a avaliação durante o treinamento usam esse modo. - como um robô simulado (
--robot.type=sim): um ambiente atrás da interfaceRobot, substituível por hardware real.lerobot-rollout,lerobot-record,lerobot-teleoperateelerobot-replayo 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 umEnvConfig. Nem todo env é um simulador:gym_manipulatorcontrola um robô real. - a sim (
lerobot.sim) é o simulador por trás de um ambiente simulado: umSimConfigque nomeia sua integração, executado porLocalVectorEnv, sem torch. - o env server (
lerobot.env_server) serve uma simulação;RemoteVectorEnva controla com a mesma API deLocalVectorEnv.
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_liberoServido: 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:7448Todas 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_idseleciona 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-evalos 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.endpointfaz 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. --fpsdeve ser igual à taxa de controle do ambiente, dividida por--interpolation_multiplierao interpolar, pois cada comando avança o ambiente uma vez. Ao gravar,--dataset.fpsdeve 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 failedouERROR_INCOMPATIBLE_DRIVERenquanto 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 porgpus: all, pode não montá-los; seu modo CDI sim. Solicite a GPU através do CDI (--device nvidia.com/gpu=allparadocker run,devices: [nvidia.com/gpu=all]no lugar degpus: allemdocker/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