LeRobot documentation
Aprendizado por Imitação em Robôs do Mundo Real
Aprendizado por Imitação em Robôs do Mundo Real
Este tutorial explicará como treinar uma rede neural para controlar um robô real de forma autônoma.
Você vai aprender:
- Como gravar e visualizar seu conjunto de dados.
- Como treinar uma política usando seus dados e prepará-la para avaliação.
- Como avaliar sua política e visualizar os resultados.
Ao seguir essas etapas, você será capaz de replicar tarefas, como pegar um bloco de Lego e colocá-lo em uma caixa, com uma alta taxa de sucesso, conforme mostrado no vídeo abaixo.
Video: pickup lego block task
Este tutorial não está vinculado a um robô específico: mostramos os comandos e trechos de API que você pode adaptar para qualquer plataforma suportada.
Durante a coleta de dados, você usará um dispositivo de “teleoperação”, como um braço líder ou um teclado, para teleoperar o robô e registrar suas trajetórias de movimento.
Depois de reunir trajetórias suficientes, você treina uma rede neural para imitar essas trajetórias e implanta o modelo treinado para que seu robô possa executar a tarefa de forma autônoma.
Se você encontrar algum problema em qualquer momento, entre na nossa comunidade do Discord para obter suporte.
Quer obter rapidamente os comandos corretos para a sua configuração? O notebook de introdução
permite configurar o seu robô uma única vez e gera todos os comandos abaixo prontos para colar.
Configurar e Calibrar
Se você ainda não configurou e calibrou seu robô e dispositivo de teleop, faça isso seguindo o tutorial para o seu robô, por exemplo SO-101, OpenArm, Koch ou LeKiwi. Todos os robôs suportados estão listados em Robots na barra lateral.
Teleoperação
Neste exemplo, demonstraremos como teleoperar o robô SO101. Para cada comando, também fornecemos um exemplo de API correspondente.
Observe que o id associado a um robô é usado para armazenar o arquivo de calibração. É importante usar o mesmo id ao teleoperar, gravar e avaliar ao usar a mesma configuração.
lerobot-teleoperate \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem58760431541 \
--robot.id=my_awesome_follower_arm \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem58760431551 \
--teleop.id=my_awesome_leader_armfrom lerobot.teleoperators.so_leader import SO101Leader, SO101LeaderConfig
from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
robot_config = SO101FollowerConfig(
port="/dev/tty.usbmodem5AB90687491",
id="my_follower_arm",
)
teleop_config = SO101LeaderConfig(
port="/dev/tty.usbmodem5AB90689011",
id="my_leader_arm",
)
robot = SO101Follower(robot_config)
teleop_device = SO101Leader(teleop_config)
robot.connect()
teleop_device.connect()
while True:
action = teleop_device.get_action()
robot.send_action(action)O comando teleoperate executará automaticamente:
- Identifique calibrações ausentes e inicie o procedimento de calibração.
- Conecte o robô e o dispositivo de teleoperação e inicie a teleoperação.
Câmeras
Para adicionar câmeras à sua configuração, siga este Guia.
Teleopere com câmeras
Com o rerun, você pode teleoperar novamente enquanto visualiza simultaneamente os feeds das câmeras e as posições das juntas. Este exemplo usa duas câmeras, wrist e top; mantemos a mesma configuração de câmeras para o restante do tutorial.
lerobot-teleoperate \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90687491 \
--robot.id=my_follower_arm \
--robot.cameras="{ wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, top: {type: opencv, index_or_path: 1, width: 640, height: 480, fps: 30}}" \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem5AB90689011 \
--teleop.id=my_leader_arm \
--display_data=trueimport time
from lerobot.teleoperators.so_leader import SO101Leader, SO101LeaderConfig
from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
from lerobot.cameras.opencv import OpenCVCameraConfig
from lerobot.utils.visualization_utils import init_visualization, log_visualization_data, shutdown_visualization
robot_config = SO101FollowerConfig(
port="/dev/tty.usbmodem5AB90687491",
id="my_follower_arm",
cameras={
"wrist": OpenCVCameraConfig(index_or_path=0, width=640, height=480, fps=30),
"top": OpenCVCameraConfig(index_or_path=1, width=640, height=480, fps=30)
}
)
teleop_config = SO101LeaderConfig(
port="/dev/tty.usbmodem5AB90689011",
id="my_leader_arm",
)
init_visualization("rerun", session_name="teleoperation") # pass "foxglove" to stream to Foxglove instead
robot = SO101Follower(robot_config)
teleop_device = SO101Leader(teleop_config)
robot.connect()
teleop_device.connect()
TARGET_HZ = 30
TIME_PER_FRAME = 1.0 / TARGET_HZ
while True:
start_time = time.perf_counter()
observation = robot.get_observation()
action = teleop_device.get_action()
robot.send_action(action)
log_visualization_data("rerun", observation=observation, action=action)
elapsed_time = time.perf_counter() - start_time
sleep_time = TIME_PER_FRAME - elapsed_time
if sleep_time > 0:
time.sleep(sleep_time)Registrar um conjunto de dados
Depois que você estiver familiarizado com a teleoperação, poderá gravar seu primeiro conjunto de dados.
Usamos os recursos do hub do Hugging Face para enviar seu dataset. Se você ainda não usou o Hub, verifique se consegue fazer login via cli usando um token de acesso de escrita; esse token pode ser gerado nas configurações do Hugging Face.
Adicione seu token ao CLI executando este comando:
hf auth login --token ${HUGGINGFACE_TOKEN} --add-to-git-credentialEm seguida, armazene o nome do seu repositório do Hugging Face em uma variável:
HF_USER=$(NO_COLOR=1 hf auth whoami | awk -F': *' 'NR==1 {print $2}')
echo $HF_USERAgora você pode gravar um conjunto de dados. Para gravar 5 episódios e enviar seu conjunto de dados para o hub, adapte o código abaixo para o seu robô e execute o comando ou o exemplo de API.
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem585A0076841 \
--robot.id=my_awesome_follower_arm \
--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30}}" \
--robot.cameras="{ wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, top: {type: opencv, index_or_path: 1, width: 640, height: 480, fps: 30}}" \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem58760431551 \
--teleop.id=my_awesome_leader_arm \
--display_data=true \
--dataset.repo_id=${HF_USER}/record-test \
--dataset.num_episodes=5 \
--dataset.single_task="Grab the black cube" \
--dataset.streaming_encoding=true \
--dataset.encoder_threads=2
# Optional: --dataset.rgb_encoder.vcodec=autofrom lerobot.cameras.opencv import OpenCVCameraConfig
from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.utils.feature_utils import hw_to_dataset_features
from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
from lerobot.teleoperators.so_leader.config_so_leader import SO101LeaderConfig
from lerobot.teleoperators.so_leader.so_leader import SO101Leader
from lerobot.common.control_utils import init_keyboard_listener
from lerobot.utils.utils import log_say
from lerobot.utils.visualization_utils import init_visualization
from lerobot.scripts.lerobot_record import record_loop
from lerobot.processor import make_default_processors
NUM_EPISODES = 5
FPS = 30
EPISODE_TIME_SEC = 60
RESET_TIME_SEC = 10
TASK_DESCRIPTION = "My task description"
def main():
# Create robot configuration
robot_config = SO101FollowerConfig(
port="/dev/tty.usbmodem5AB90687491",
id="my_follower_arm",
cameras={
"wrist": OpenCVCameraConfig(index_or_path=0, width=640, height=480, fps=30),
"top": OpenCVCameraConfig(index_or_path=1, width=640, height=480, fps=30)
}
)
teleop_config = SO101LeaderConfig(
port="/dev/tty.usbmodem5AB90689011",
id="my_leader_arm",
)
# Initialize the robot and teleoperator
robot = SO101Follower(robot_config)
teleop = SO101Leader(teleop_config)
# Configure the dataset features
action_features = hw_to_dataset_features(robot.action_features, "action")
obs_features = hw_to_dataset_features(robot.observation_features, "observation")
dataset_features = {**action_features, **obs_features}
# Create the dataset
dataset = LeRobotDataset.create(
repo_id="<hf_username>/<dataset_repo_id>",
fps=FPS,
features=dataset_features,
robot_type=robot.name,
use_videos=True,
image_writer_threads=4,
)
# Initialize the keyboard listener and rerun visualization
_, events = init_keyboard_listener()
init_visualization("rerun", session_name="recording")
# Connect the robot and teleoperator
robot.connect()
teleop.connect()
# Create the required processors
teleop_action_processor, robot_action_processor, robot_observation_processor = make_default_processors()
episode_idx = 0
while episode_idx < NUM_EPISODES and not events["stop_recording"]:
log_say(f"Recording episode {episode_idx + 1} of {NUM_EPISODES}")
record_loop(
robot=robot,
events=events,
fps=FPS,
teleop_action_processor=teleop_action_processor,
robot_action_processor=robot_action_processor,
robot_observation_processor=robot_observation_processor,
teleop=teleop,
dataset=dataset,
control_time_s=EPISODE_TIME_SEC,
single_task=TASK_DESCRIPTION,
display_data=True,
)
# Reset the environment if not stopping or re-recording
if not events["stop_recording"] and (episode_idx < NUM_EPISODES - 1 or events["rerecord_episode"]):
log_say("Reset the environment")
record_loop(
robot=robot,
events=events,
fps=FPS,
teleop_action_processor=teleop_action_processor,
robot_action_processor=robot_action_processor,
robot_observation_processor=robot_observation_processor,
teleop=teleop,
control_time_s=RESET_TIME_SEC,
single_task=TASK_DESCRIPTION,
display_data=True,
)
if events["rerecord_episode"]:
log_say("Re-recording episode")
events["rerecord_episode"] = False
events["exit_early"] = False
dataset.clear_episode_buffer()
continue
dataset.save_episode()
episode_idx += 1
# finalize dataset
log_say("Finalizing dataset...")
dataset.finalize()
# Clean up
log_say("Stop recording")
robot.disconnect()
teleop.disconnect()
dataset.push_to_hub()
if __name__ == "__main__":
main()Os nomes das câmeras que você escolher (aqui wrist e top) se tornam as chaves do dataset observation.images.wrist e observation.images.top. Uma política treinada neste dataset espera os mesmos nomes de câmeras e resolução quando você a implantar, então reutilize o mesmo valor de --robot.cameras em cada etapa deste tutorial. Se os nomes tiverem que ser diferentes, consulte Rename Map.
lerobot-recordadiciona a data e a hora da sessão ao final de--dataset.repo_id, de modo que cada gravação receba um nome único:${HF_USER}/record-testé salvo como${HF_USER}/record-test_YYYYMMDD_HHMMSS(por exemplo,record-test_20260929_143012). Encontre o nome completo no seu perfil do Hugging Face ou comls ~/.cache/huggingface/lerobot/${HF_USER}, e use-o em todos os lugares em que os comandos abaixo indicamrecord-test_YYYYMMDD_HHMMSS. Para manter exatamente o nome que você passou, adicione--dataset.no_stamp=true.
Upload de dataset
Localmente, seu conjunto de dados é armazenado nesta pasta: ~/.cache/huggingface/lerobot/{repo-id}. Ao final da gravação dos dados, seu conjunto de dados será enviado para a sua página do Hugging Face (por exemplo, https://huggingface.co/datasets/${HF_USER}/record-test_YYYYMMDD_HHMMSS), que você pode obter executando:
echo https://huggingface.co/datasets/${HF_USER}/record-test_YYYYMMDD_HHMMSSSeu conjunto de dados será automaticamente marcado com LeRobot para que a comunidade o encontre facilmente, e você também pode adicionar tags personalizadas, por exemplo --dataset.tags='["tutorial"]'.
Você pode procurar por outros conjuntos de dados do LeRobot no hub pesquisando pelas tags LeRobot.
Você também pode enviar seu dataset local para o Hub manualmente, executando:
hf upload ${HF_USER}/record-test_YYYYMMDD_HHMMSS ~/.cache/huggingface/lerobot/${HF_USER}/record-test_YYYYMMDD_HHMMSS --repo-type datasetFunção de registro
lerobot-record fornece um conjunto de ferramentas para capturar e gerenciar dados durante a operação do robô:
1. Armazenamento de dados
- Os dados são armazenados no formato
LeRobotDatasete são gravados em disco durante a gravação. - Por padrão, o conjunto de dados é enviado para a sua página do Hugging Face após a gravação.
- Para desativar o upload, use
--dataset.push_to_hub=False.
- Para desativar o upload, use
2. Checkpointing e Retomada
- Os checkpoints são criados automaticamente durante a gravação.
- Se um problema ocorrer ou você quiser gravar episódios adicionais no mesmo dataset, é possível retomar reexecutando o mesmo comando com
--resume=true. Passe o nome completo do dataset, incluindo seu timestamp (--dataset.repo_id=${HF_USER}/record-test_YYYYMMDD_HHMMSS). Ao retomar uma gravação,--dataset.num_episodesdeve ser definido para o número de episódios adicionais a serem gravados, e não para o número total de episódios alvo no dataset! Certifique-se de que você também defina--dataset.root="local_path", pois é um caminho local para salvar a nova parte do dataset e é obrigatório para retomar. - Executar o comando novamente sem
--resume=trueinicia um novo conjunto de dados com um novo timestamp. Se você usar--dataset.no_stamp=true, exclua primeiro o diretório do conjunto de dados existente.
3. Parâmetros de gravação
Defina o fluxo de gravação de dados usando argumentos de linha de comando:
--dataset.episode_time_s=60Duração de cada episódio de gravação de dados (padrão: 60 segundos).--dataset.reset_time_s=60Duração para redefinir o ambiente após cada episódio (padrão: 60 segundos).--dataset.num_episodes=50Número total de episódios a serem registrados (padrão: 50).
4. Controles de teclado durante a gravação
Controle o fluxo de gravação de dados usando atalhos de teclado:
- Pressione Seta para a direita (
→) oun: interrompe precocemente o episódio atual ou redefine o tempo e avança para o próximo. - Pressione Seta para a esquerda (
←) our: cancela o episódio atual e o grava novamente. - Pressione Escape (
ESC) ouq: interrompe imediatamente a sessão, codifica os vídeos e faz o upload do conjunto de dados.
Esses atalhos de fluxo de controle funcionam em sessões X11, Wayland e headless/SSH. Quando um backend global de teclado não está disponível (Wayland, uma máquina headless ou macOS sem permissão de Acessibilidade), o
lerobot-recordlê automaticamente as mesmas teclas do terminal — inicie-o a partir de um terminal interativo e mantenha-o em foco. Você também pode usar os equivalentes em letrasn(próximo, igual a→),r(regravar, igual a←) eq(sair, igual aESC). Não é necessário configurar o$DISPLAY.Isso se aplica apenas ao fluxo de controle de gravação. A teleoperação por teclado (dirigir o robô com o teclado) ainda requer um backend global de teclas, portanto, funciona apenas em uma sessão X11, em um desktop Windows ou no macOS com permissões de Acessibilidade/Monitoramento de Entrada concedidas — não em sessões Wayland ou headless.
Dicas para coletar dados
Quando você estiver confortável com a gravação de dados, pode criar um conjunto de dados maior para o treinamento. Uma boa tarefa inicial é pegar um objeto em diferentes localizações e colocá-lo em um recipiente. Sugerimos gravar pelo menos 50 episódios, com 10 episódios por localização. Mantenha as câmeras fixas e mantenha um comportamento de pegada consistente ao longo das gravações. Certifique-se também de que o objeto que você está manipulando esteja visível nas câmeras. Uma boa regra geral é que você deve ser capaz de executar a tarefa sozinho olhando apenas para as imagens das câmeras.
Nas seções a seguir, você treinará sua rede neural. Após alcançar um desempenho confiável de preensão, você pode começar a introduzir mais variações durante a coleta de dados, como locais adicionais de preensão, diferentes técnicas de preensão e alterações nas posições da câmera.
Evite adicionar muita variação muito rapidamente, pois isso pode prejudicar seus resultados.
Se você deseja se aprofundar neste tópico importante, pode conferir o post no blog que escrevemos sobre o que torna um bom dataset.
Relatórios de cadência
lerobot-record controla o ritmo do loop em --dataset.fps e relata o que foi realmente alcançado: um resumo em uma linha para cada episódio que você mantém e um bloco para toda a sessão quando a gravação termina — inclusive em caso de Ctrl-C.
Cadence (episode 0): 29.88 Hz vs 30 Hz target · 600 ticks, 20.0 s measured · 8/599 ticks over the 33.3 ms budget (work mean 18.4 ms, worst 45.1 ms)
Cadence (episode 1): 29.88 Hz vs 30 Hz target · 600 ticks, 20.0 s measured · 8/599 ticks over the 33.3 ms budget (work mean 18.4 ms, worst 45.1 ms)
Cadence summary — whole run, 2 episodes · target 30 Hz (33.3 ms budget per tick): 1200 ticks, 1198 judged
effective cadence: 29.88 Hz over 40.1 s measured
ticks over the 33.3 ms work budget: 16/1198 (1.3%) — work mean 18.4 ms, worst 45.1 ms
loop-body steps (share of measured work):
observe mean 13.65 ms · worst 40.20 ms · 74.4% of work · 1200 calls
process_obs mean 0.30 ms · worst 0.30 ms · 1.6% of work · 1200 calls
teleop mean 1.80 ms · worst 1.80 ms · 9.8% of work · 1200 calls
send mean 0.90 ms · worst 0.90 ms · 4.9% of work · 1200 calls
record mean 1.70 ms · worst 1.90 ms · 9.3% of work · 1200 calls
pacing headroom: 15.1 ms slept per tick on average (max 16.7 ms) — near zero means the loop is saturatedVale a pena ler isso antes de treinar no dataset. O timestamp de um frame é derivado do seu índice, então uma sessão que rodou a 25 Hz ainda produz um dataset que afirma 30 — o movimento registrado é simplesmente mais rápido que a realidade. Acima, observe é 74% do trabalho do loop e seu worst é 40 ms em um orçamento de 33,3 ms: foram as câmeras que empurraram aqueles 16 ticks para além. Margem de ritmo próxima de zero significa que não há mais nada para absorver um tick lento.
As fases de reset entre episódios são ritmadas da mesma forma, mas são deliberadamente excluídas desses números, pois não registram nada. lerobot-teleoperate e lerobot-replay relatam da mesma forma, e lerobot-rollout adiciona as linhas específicas de interpolação descritas em Relatório de Cadência.
Solução de problemas:
- No Linux, as teclas de controle de fluxo de gravação (teclas de seta, Escape) funcionam em X11, Wayland e sessões headless/SSH, desde que o
lerobot-recordseja executado em um terminal interativo — não é necessário configurar o$DISPLAY. Se as teclas não tiverem efeito, verifique se você está em um terminal interativo (TTY), e não em uma sessão piped/não-TTY, e se ele está em foco; os equivalentes em letrasn/r/qtambém funcionam. A teleoperação por teclado (em oposição ao fluxo de controle de gravação) ainda requer um backend global de teclas — uma sessão X11, um desktop Windows ou macOS com permissões de Acessibilidade/Monitoramento de Entrada concedidas — e não está disponível em Wayland ou em máquinas headless. Consulte limitações do pynput.
Visualizar um conjunto de dados
Seu conjunto de dados é enviado ao Hub por padrão (a menos que você tenha passado --dataset.push_to_hub=False), então você pode abri-lo no LeRobot Dataset Visualizer imediatamente: insira o id do seu repositório na página inicial ou vá direto para o primeiro episódio com o link que isso imprime:
echo "https://huggingface.co/spaces/lerobot/visualize_dataset?path=/${HF_USER}/record-test_YYYYMMDD_HHMMSS/episode_0"Faça login no visualizador para abrir um conjunto de dados privado. Consulte Explore a Dataset in the Browser para um passo a passo.
Reproduzir um episódio
Um recurso útil é a função replay, que permite reproduzir qualquer episódio que você tenha gravado ou episódios de qualquer dataset disponível. Essa função ajuda a testar a repetibilidade das ações do seu robô e a avaliar a transferibilidade entre robôs do mesmo modelo.
Você pode reproduzir o primeiro episódio no seu robô com o comando abaixo ou com o exemplo de API:
lerobot-replay \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem58760431541 \
--robot.id=my_awesome_follower_arm \
--dataset.repo_id=${HF_USER}/record-test_YYYYMMDD_HHMMSS \
--dataset.episode=0 # choose the episode you want to replayimport time
from lerobot.datasets import LeRobotDataset
from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
from lerobot.utils.robot_utils import precise_sleep
from lerobot.utils.utils import log_say
episode_idx = 0
robot_config = SO101FollowerConfig(port="/dev/tty.usbmodem5AB90687491", id="my_follower_arm")
robot = SO101Follower(robot_config)
robot.connect()
dataset = LeRobotDataset("<hf_username>/<dataset_repo_id>", episodes=[episode_idx])
actions = dataset.select_columns("action")
log_say(f"Replaying episode {episode_idx}")
for idx in range(dataset.num_frames):
t0 = time.perf_counter()
action = {
name: float(actions[idx]["action"][i]) for i, name in enumerate(dataset.features["action"]["names"])
}
robot.send_action(action)
precise_sleep(max(1.0 / dataset.fps - (time.perf_counter() - t0), 0.0))
robot.disconnect()Seu robô deve replicar movimentos semelhantes aos que você gravou. Por exemplo, confira este vídeo em que usamos replay em um robô ALOHA da Trossen Robotics.
Treinar uma política
Para treinar uma política para controlar seu robô, use o script lerobot-train. Alguns argumentos são obrigatórios. Aqui está um exemplo de comando:
lerobot-train \
--dataset.repo_id=${HF_USER}/record-test_YYYYMMDD_HHMMSS \
--policy.type=act \
--output_dir=outputs/train/act_so101_test \
--job_name=act_so101_test \
--policy.device=cuda \
--trackio.enable=true \
--policy.repo_id=${HF_USER}/my_policyVamos explicar o comando:
- Fornecemos o dataset gravado anteriormente como argumento com
--dataset.repo_id=${HF_USER}/record-test_YYYYMMDD_HHMMSS(use o nome completo do seu dataset, incluindo o timestamp). - Fornecemos a política com
policy.type=act. Isso carrega as configurações deconfiguration_act.py. É importante destacar que esta política se adaptará automaticamente ao número de estados dos motores, ações dos motores e câmeras do seu robô (por exemplo,wristetop) que foram salvos no seu conjunto de dados. - Fornecemos
policy.device=cudaporque estamos treinando em uma GPU Nvidia, mas você pode usarpolicy.device=mpspara treinar em Apple silicon. - Fornecemos
trackio.enable=truepara usar o Trackio na visualização dos gráficos de treinamento. Isso é opcional. Executetrackio show --project lerobotpara abrir o painel de controle ou passe--trackio.space_id=<user>/<space>para sincronizar a execução com um Hugging Face Space. - Não definimos
--steps, portanto o treinamento é executado para o padrão de 100.000 passos. Isso geralmente é mais do que um pequeno conjunto de dados precisa: o aprendizado por imitação normalmente converge dentro de 5 a 10 épocas sobre os dados. Consulte o Guia de Computação e Hardware para converter épocas em um valor de--stepspara o tamanho do seu conjunto de dados e tamanho do lote.
O treinamento deve levar algumas horas. Você encontrará os checkpoints em outputs/train/act_so101_test/checkpoints.
Para retomar o treinamento a partir de um checkpoint, abaixo está um exemplo de comando para retomar do checkpoint last da política act_so101_test:
lerobot-train \
--config_path=outputs/train/act_so101_test/checkpoints/last/pretrained_model/train_config.json \
--resume=true--config_path também aceita um Hub repo id: se uma execução enviou seus checkpoints para o Hub (com --save_checkpoint_to_hub=true), você pode retomar diretamente do repositório — o checkpoint mais recente é baixado e o treinamento continua, restaurando o otimizador, o agendador, o contador de etapas e a ordem dos dados:
lerobot-train --config_path=${HF_USER}/my_policy --resume=trueSe você não deseja enviar seu modelo para o hub após o treinamento, use --policy.push_to_hub=false.
Além disso, você pode fornecer tags extras ou especificar uma license para seu modelo ou tornar o repositório do modelo private adicionando o seguinte: --policy.private=true --policy.tags=\[so101,tutorial\] --policy.license=mit
Treinar usando o Google Colab
Se o seu computador local não possui uma GPU potente, você pode utilizar o Google Colab para treinar seu modelo seguindo o notebook de treinamento ACT.
Treinar usando Hugging Face Jobs
Hugging Face Jobs permite selecionar facilmente o hardware e executar o treinamento na nuvem. Portanto, se você não possui uma GPU potente, precisa de mais VRAM ou simplesmente deseja treinar um modelo muito mais rápido, use o HF Jobs! O modelo é de pagamento por uso e você paga apenas por cada segundo de utilização. Você pode ver a tabela de preços e informações adicionais aqui.
lerobot-train é executado localmente por padrão. Para executar em uma GPU da HuggingFace, passe --job.target com o nome de um sabor de hardware:
lerobot-train \
--dataset.repo_id=${HF_USER}/record-test_YYYYMMDD_HHMMSS \
--policy.type=act \
--policy.repo_id=${HF_USER}/my_policy \
--job.target=a10g-smallListe os sabores e preços disponíveis com hf jobs hardware. A execução transmite os logs para o seu terminal; pressione Ctrl-C para se desconectar (o job continua rodando na nuvem). Reconecte ou cancele com:
hf jobs logs <job-id>
hf jobs cancel <job-id>Se o seu conjunto de dados existir apenas localmente (ainda não no Hub), ele é enviado automaticamente para um repositório privado do Hub para que o job possa baixá-lo por repo_id (nada é tornado público). O modelo treinado é enviado para o repositório do modelo ao final da execução. Para também enviar cada checkpoint intermediário para o Hub conforme é salvo (para que você possa monitorar o progresso durante a execução), adicione --save_checkpoint_to_hub=true — isso requer uma imagem de runtime que inclua esse recurso.
Cada job (e qualquer dataset enviado pela execução) é marcado com lerobot para facilitar a localização no Hub. Adicione os seus com --job.tags '["my-tag"]'.
Por padrão, o job é limitado a 2d (48h) de tempo real. Substitua esse valor com uma string de duração de HF Jobs, por exemplo, --job.timeout=4h para falhar mais rápido ou --job.timeout=7d para uma execução mais longa.
Observação: o repositório do modelo é criado previamente (ele contém a configuração de treinamento preparada que a tarefa executa). Se uma execução falhar antes de o modelo ser enviado, esse repositório permanece no Hub para que você possa inspecioná-lo — ele não é excluído automaticamente, portanto, falhas repetidas podem deixar repositórios vazios. Remova um com
hf repos delete <repo-id>.
Pré-requisitos: execute hf auth login antes de enviar. Para o Trackio, passe --trackio.space_id=<user>/<space> — o Space é criado se não existir e o HF_TOKEN do job é encaminhado automaticamente.
Retomando em um job. Adicionar --job.target a um comando de retomada executa a retomada na nuvem — o mesmo comando funciona localmente ou remotamente. O repositório de checkpoint é a fonte da verdade, e novos checkpoints continuam a linhagem no mesmo repositório:
# resume a Hub run on a job (its checkpoints are already on the Hub)
lerobot-train --config_path=${HF_USER}/my_policy --resume=true --job.target=a10g-small
# resume a LOCAL run on a job — the checkpoint is uploaded to a private Hub repo first,
# then the job resumes from it (a local-only dataset is uploaded the same way)
lerobot-train \
--config_path=outputs/train/act_so101_test/checkpoints/last/pretrained_model/train_config.json \
--resume=true \
--job.target=a10g-smallAs configurações do job vêm do comando atual, portanto, substitua --job.target, --job.timeout etc. conforme necessário; para que a execução retomada possa ser retomada novamente no futuro, mantenha --save_checkpoint_to_hub=true.
Upload de pontos de verificação de políticas
Quando o treinamento estiver concluído, envie o checkpoint mais recente com:
hf upload ${HF_USER}/act_so101_test \
outputs/train/act_so101_test/checkpoints/last/pretrained_modelVocê também pode enviar checkpoints intermediários com:
CKPT=010000
hf upload ${HF_USER}/act_so101_test${CKPT} \
outputs/train/act_so101_test/checkpoints/${CKPT}/pretrained_modelExecute inferência e avalie sua política
Use o lerobot-rollout para implantar uma política treinada no seu robô. Você pode escolher diferentes estratégias de acordo com suas necessidades.
Use o mesmo --robot.id (para que a calibração seja encontrada), o mesmo --robot.cameras e a mesma descrição da tarefa do seu conjunto de dados gravado. Conjuntos de dados gravados por lerobot-rollout devem ter um nome que comece com rollout_, e, assim como o lerobot-record, ele adiciona um timestamp a esse nome.
Os exemplos abaixo carregam o modelo a partir de --policy.path. Para fixar uma versão específica enviada — útil depois que --save_checkpoint_to_hub=true tiver commitado vários checkpoints — adicione --policy.pretrained_revision com um hash de commit, branch ou tag. Cada checkpoint enviado é marcado com seu passo (por exemplo, --policy.pretrained_revision=010000), permitindo recuperar um checkpoint pelo passo sem precisar buscar seu sha de commit.
lerobot-rollout \
--strategy.type=base \
--policy.path=${HF_USER}/my_policy \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90687491 \
--robot.id=my_follower_arm \
--robot.cameras="{ wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, top: {type: opencv, index_or_path: 1, width: 640, height: 480, fps: 30}}" \
--task="Grab the black cube" \
--duration=60lerobot-rollout \
--strategy.type=sentry \
--strategy.upload_every_n_episodes=5 \
--policy.path=${HF_USER}/my_policy \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90687491 \
--robot.id=my_follower_arm \
--robot.cameras="{ wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, top: {type: opencv, index_or_path: 1, width: 640, height: 480, fps: 30}}" \
--dataset.repo_id=${HF_USER}/rollout_so101_test \
--dataset.single_task="Grab the black cube" \
--duration=600A flag --strategy.type seleciona o modo de execução:
base: Rollout autônomo sem gravação de dados (útil para avaliação rápida)sentry: Gravação contínua com upload automático (útil para avaliação em larga escala)highlight: Gravação em buffer circular com salvamento por tecla (útil para capturar eventos interessantes)dagger: Coleta de dados com intervenção humana (veja HIL Data Collection)episodic: Gravação de política orientada a episódios com fases de reinício entre episódios
Todas as estratégias suportam --inference.type=rtc para uma execução suave com modelos VLA lentos (Pi0, Pi0.5, SmolVLA). Consulte Policy Deployment para todas as estratégias e suas flags.