LeRobot documentation

Política π₀.₅ (Pi05)

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Política π₀.₅ (Pi05)

π₀.₅ é um modelo Vision-Language-Action com generalização em mundo aberto, da Physical Intelligence. A implementação do LeRobot é adaptada do repositório de código aberto OpenPI deles.

Visão geral do modelo

π₀.₅ representa uma evolução significativa em relação ao π₀, desenvolvido pela Physical Intelligence para enfrentar um grande desafio na robótica: a generalização em mundo aberto. Embora os robôs possam executar tarefas impressionantes em ambientes controlados, o π₀.₅ foi projetado para se generalizar a ambientes e situações totalmente novos que nunca foram vistos durante o treinamento.

O Desafio da Generalização

Conforme a Physical Intelligence explica, o desafio fundamental não é executar tarefas de agilidade ou destreza, mas sim a generalização, a capacidade de executar corretamente tarefas em novos ambientes com novos objetos. Considere um robô limpando casas diferentes: cada casa tem objetos diferentes em lugares diferentes. A generalização deve ocorrer em múltiplos níveis:

  • Nível físico: Compreender como pegar uma colher (pelo cabo) ou um prato (pela borda), mesmo com objetos não vistos em ambientes desorganizados
  • Nível Semântico: Compreensão da semântica da tarefa, como onde colocar roupas e sapatos (no cesto de roupa suja, não na cama) e quais ferramentas são apropriadas para limpar derramamentos
  • Nível ambiental: Adaptação a ambientes reais “caóticos”, como residências, supermercados, escritórios e hospitais

Co-Training em Dados Heterogêneos

A inovação disruptiva do π₀.₅ é o co-treinamento em fontes de dados heterogêneas. O modelo aprende a partir de:

  1. Dados Web Multimodais: legendagem de imagens, resposta a perguntas visuais, detecção de objetos
  2. Instruções verbais: Humanos orientando robôs em tarefas complexas passo a passo
  3. Comandos de subtarefas: Rótulos de comportamento semântico de alto nível (por exemplo, “pegue o travesseiro” para uma cama desfeita)
  4. Dados de robôs de múltiplas plataformas: Dados de diversas plataformas de robôs com diferentes capacidades
  5. Dados de múltiplos ambientes: robôs estáticos implantados em muitos lares diferentes
  6. Dados de Manipulação Móvel: ~400 horas de demonstrações de robôs móveis

Essa mistura de treinamento diversificada cria um “currículo” que permite a generalização simultânea nos níveis físico, visual e semântico.

Requisitos de instalação

  1. Instale o LeRobot seguindo nosso Guia de Instalação.

  2. Instale as dependências do Pi0.5 executando:

    pip install -e ".[pi]"

    Se você instalou o LeRobot a partir do PyPI:

    pip install 'lerobot[pi]'

Uso

Para usar π₀.₅ na sua configuração do LeRobot, especifique o tipo de política como:

policy.type=pi05

Treinamento

Início rápido no LIBERO

Ajuste o modelo base do LIBERO em lerobot/libero, uma cópia codificada em vídeo de ~1,9 GB das demonstrações por trás dos resultados abaixo.

Ele contém as chaves que o π₀.₅ lê, que também são as produzidas pelo ambiente LIBERO no momento da avaliação:

RecursoFormato no conjunto de dadosComo o π₀.₅ o consome
observation.images.image256×256×3, agentviewredimensionado para 224×224
observation.images.image2256×256×3, pulsoredimensionado para 224×224
observation.state8discretizado em 256 bins e escrito no prompt
action7preenchido com zeros até 32 internamente; a perda usa as primeiras 7 dimensões

Não é necessário usar --rename_map aqui — as chaves já correspondem; consulte Rename Map and Empty Cameras se as suas forem diferentes.

π₀.₅ uses the gated [google/paligemma-3b-pt-224](https://huggingface.co/google/paligemma-3b-pt-224) tokenizer — accept its license on the Hub and log in with `hf auth login` before training.

Dimensionado para uma única GPU de 80 GB:

lerobot-train \
    --dataset.repo_id=lerobot/libero \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_libero_base \
    --policy.normalization_mapping='{"ACTION": "MEAN_STD", "STATE": "MEAN_STD", "VISUAL": "IDENTITY"}' \
    --policy.n_action_steps=10 \
    --policy.empty_cameras=1 \
    --policy.freeze_vision_encoder=false \
    --policy.train_expert_only=false \
    --policy.gradient_checkpointing=true \
    --policy.dtype=bfloat16 \
    --policy.device=cuda \
    --policy.push_to_hub=false \
    --output_dir=./outputs/pi05_libero \
    --job_name=pi05_libero \
    --batch_size=64 \
    --num_workers=8 \
    --steps=30000 \
    --save_freq=5000 \
    --seed=1000

Normalização por média/desvio padrão, não o padrão de quantil do π₀.₅ — correspondendo a pi05_libero_finetuned_v044, o checkpoint em que os resultados abaixo foram medidos.

--policy.n_action_steps=10 e --policy.empty_cameras=1 são explícitos porque --policy.pretrained_path carrega apenas os pesos — lerobot/pi05_libero_base armazena ambos, e, caso contrário, eles reverteriam para 50 e 0 (veja Carregando um checkpoint).

Em seguida, avalie um checkpoint com lerobot-eval e compare com as taxas de sucesso de referência — veja LIBERO.

Estatísticas de quantis

π₀.₅ normaliza STATE e ACTION com quantis, portanto o meta/stats.json do seu conjunto de dados precisa de q01 e q99. Conjuntos de dados mais antigos contêm apenas min/max/mean/std e falham no primeiro lote:

ValueError: QUANTILES normalization mode requires q01 and q99 stats

Recalcule-os:

lerobot-edit-dataset \
    --repo_id your_dataset \
    --new_repo_id your_dataset \
    --operation.type recompute_stats \
    --operation.overwrite true

The result lands in $HF_LEROBOT_HOME/your_dataset, not the cache --dataset.repo_id reads — so train with --dataset.root=$HF_LEROBOT_HOME/your_dataset, or add --push_to_hub true above.

Ou mantenha o dataset como está e passe --policy.normalization_mapping='{"ACTION": "MEAN_STD", "STATE": "MEAN_STD", "VISUAL": "IDENTITY"}'.

Gravar, retomar e mesclar quantis agregados a partir de resumos por episódio, para que meta/stats.json acabe contendo um envelope conservador (min para q <= 50, max para q > 50) em vez de quantis do conjunto de dados inteiro. Para estimar estes últimos, percorra todos os episódios com um histograma incremental:

python src/lerobot/scripts/augment_dataset_quantile_stats.py \
    --repo-id=your_dataset \
    --overwrite \
    --skip-images

--skip-images mantém as estatísticas de imagem existentes e evita o download ou a decodificação de dados de vídeo quando apenas STATE/ACTION precisam ser recalculados, e --root lê um dataset local em vez do Hub. Esses valores são estimativas de histograma, sujeitas a erros de discretização e rebinning, portanto podem diferir dos conservadores — o que altera os alvos normalizados do π₀.₅ e, consequentemente, a escala de sua perda. Estatísticas já salvas dentro de um checkpoint existente não são afetadas.

Exemplo de Comando de Treinamento

O mesmo finetune com o VLM congelado: menos memória, a um certo custo na taxa de sucesso. Substitua --dataset.repo_id pelo seu próprio dataset.

lerobot-train \
    --dataset.repo_id=lerobot/libero \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_libero_base \
    --policy.normalization_mapping='{"ACTION": "MEAN_STD", "STATE": "MEAN_STD", "VISUAL": "IDENTITY"}' \
    --policy.n_action_steps=10 \
    --policy.empty_cameras=1 \
    --policy.freeze_vision_encoder=true \
    --policy.train_expert_only=true \
    --policy.gradient_checkpointing=true \
    --policy.dtype=bfloat16 \
    --policy.device=cuda \
    --policy.push_to_hub=false \
    --output_dir=./outputs/pi05_libero_expert \
    --job_name=pi05_libero_expert \
    --batch_size=64 \
    --num_workers=8 \
    --steps=30000 \
    --save_freq=5000 \
    --seed=1000

Parâmetros Principais de Treinamento

  • --policy.compile_model=true: Habilita a compilação do modelo para um treinamento mais rápido
  • --policy.gradient_checkpointing=true: reduz significativamente o uso de memória durante o treinamento
  • --policy.dtype=bfloat16: Use treinamento com precisão mista para eficiência
  • --batch_size=64: Tamanho do lote para o treinamento, adapte com base na memória da sua GPU
  • --policy.pretrained_path=lerobot/pi05_base: O modelo base π₀.₅ que você deseja fazer o finetuning. As opções são:
  • --policy.optimizer_fused=true: Usa AdamW fundido para etapas de otimizador mais rápidas; essa flag é ignorada ao retomar uma execução

RTC opcional em tempo de treinamento

Pi05 pode aprender opcionalmente condicionamento de prefixo de ação para Real-Time Chunking eficiente, seguindo Training-Time Action Conditioning for Efficient Real-Time Chunking. Defina policy.rtc_training_max_delay para o maior atraso de inferência esperado em passos do controlador:

lerobot-train \
    --dataset.repo_id=${HF_USER}/my_dataset \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_base \
    --policy.rtc_training_max_delay=10 \
    --policy.dtype=bfloat16 \
    --policy.device=cuda \
    --batch_size=8 \
    --steps=30000 \
    --output_dir=outputs/pi05_rtc \
    --job_name=pi05_rtc

O padrão é 0, o que desativa o RTC durante o treinamento e mantém o objetivo padrão do Pi05 inalterado. O atraso configurado deve ser menor que chunk_size. Durante o treinamento, o Pi05 amostra um comprimento de prefixo limpo independentemente para cada exemplo e calcula a perda de fluxo apenas no sufixo restante.

Use o checkpoint resultante com o RTC treinado explicitamente:

lerobot-rollout \
    --strategy.type=base \
    --policy.path=outputs/pi05_rtc/checkpoints/last/pretrained_model \
    --inference.type=rtc \
    --inference.rtc.mode=trained \
    --inference.rtc.execution_horizon=10 \
    --robot.type=so100_follower \
    --robot.port=/dev/ttyACM0 \
    --task="pick up the cube" \
    --fps=50 \
    --device=cuda

Defina inference.rtc.execution_horizon entre o rtc_training_max_delay do checkpoint e chunk_size - rtc_training_max_delay, e inference.queue_threshold para pelo menos rtc_training_max_delay. Um pico de latência isolado fora da faixa treinada descarta aquele chunk e tenta novamente; o rollout para com um erro explícito apenas se o atraso permanecer fora da faixa. O padrão --inference.rtc.mode=guided continua disponível para checkpoints comuns.

Carregando um checkpoint

As duas formas não são intercambiáveis:

--policy.path--policy.pretrained_path
Carregamentospesos e o config.json do checkpointsomente pesos
Nomes de recursosdo checkpointdo seu conjunto de dados, após --rename_map
Configurações armazenadas, por exemplo, n_action_stepsherdadorestaurar para os padrões
--policy.typedeve ser omitidoobrigatório
--rename_mapnecessário quando suas teclas de câmera diferemsuportado para a normalização de chaves de conjuntos de dados

Use --rename_map com qualquer forma de carregamento quando os nomes das features do dataset bruto diferem dos nomes das features da policy. Por exemplo, o comando de fine-tuning do RoboMME mapeia suas colunas brutas image, wrist_image, state e actions ao inicializar os pesos com --policy.pretrained_path.

Parâmetros de Treinamento Explicados

ParâmetroPadrãoDescrição
freeze_vision_encoderfalseNão congele o codificador de visão
train_expert_onlyfalseNão congele o VLM, treine todos os parâmetros

💡 Dica: Definir train_expert_only=true congela o VLM e treina apenas o especialista de ação e as projeções, permitindo o ajuste fino com uso reduzido de memória.

Memória de Observação de Curto Prazo (MEM)

Pi05 pode usar opcionalmente contexto visual e proprioceptivo de curto horizonte com base em MEM. Ambos os caminhos estão desativados por padrão, de modo que os checkpoints e comandos de treinamento existentes mantêm o comportamento de quadro único do Pi05.

Isso implementa apenas a memória de curto prazo do MEM — o codificador de vídeo da seção III-C e a projeção proprioceptiva da seção III-D. A memória de longo prazo linguística do MEM (seção III-B), na qual uma política de alto nível prevê o próximo subtarefa e um resumo em linguagem natural comprimido do que aconteceu até o momento, não está implementada. Nas ablações do artigo, a memória de vídeo sozinha recupera apenas parte do progresso de tarefa do MEM completo em tarefas de longo prazo.

Introduzir memória ao fazer fine-tuning a partir de um checkpoint que foi pré-treinado sem ela também corresponde à ablação mais fraca do paper, MEM-Posttrain-Only. Os principais resultados do MEM vêm do pré-treinamento do encoder de vídeo em uma mistura diversificada de vídeos de robôs e não-robôs, o que nenhum checkpoint público do Pi05 atualmente fornece.

Ative-o durante o ajuste fino com:

lerobot-train \
    --dataset.repo_id=your_dataset \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_base \
    --policy.use_visual_memory=true \
    --policy.memory_frames=6 \
    --policy.memory_stride=30 \
    --policy.memory_temporal_attention_every=4 \
    ...

memory_frames inclui a observação atual. memory_stride é medido em frames do dataset, não em segundos, portanto, escale-o com o fps do seu dataset: o MEM é pré-treinado com seis observações a um segundo de intervalo, o que corresponde a memory_stride=30 para um dataset de 30 fps (o padrão), mas a memory_stride=10 para um dataset de 10 fps, como o lerobot/robomme.

A cada quarta camada do SigLIP, a atenção é substituída pela atenção espaço-temporal composta do MEM: atenção temporal causal entre tokens de patch correspondentes, composta com a atenção espacial padrão e reutilizando as projeções pré-treinadas, de modo que nenhum parâmetro aprendível é adicionado à torre de visão. Os tokens de quadros anteriores são descartados assim que a última dessas camadas é executada, mantendo o comprimento do prefixo de linguagem/ação a jusante inalterado.

O histórico indisponível no início de um episódio é preenchido e mascarado. Na inferência, o Pi05 mantém internamente o mesmo histórico de imagens com passo e o limpa sempre que a política é reiniciada.

A propriocepção histórica é uma opção independente:

--policy.use_proprioceptive_memory=true

Quando habilitado, um token de estado contínuo projetado é adicionado para cada quadro retido, e o estado discretizado é removido do prompt de texto para que o estado seja representado exatamente uma vez (seção III-D de MEM). Isso altera o formato do prompt, portanto, habilite-o desde o início do treinamento, e não no meio do processo. A memória visual e a memória proprioceptiva usam as mesmas configurações de memory_frames e memory_stride, mas qualquer um dos caminhos pode ser habilitado de forma independente. Treine ou faça o ajuste fino com as opções de memória selecionadas; habilitá-las apenas na inferência não confere ao checkpoint de quadro único o comportamento de memória aprendido.

No PEFT, proprio_history_proj é treinado e salvo por completo via modules_to_save, pois não possui pesos pré-treinados para adaptar.

Na inferência, o MEM mantém uma única fila de histórico em lote e pressupõe que cada linha do lote compartilhe as fronteiras dos episódios. O lerobot-eval atende a isso chamando policy.reset() antes de cada rollout em lote e antes de redefinir o ambiente vetorial. A redefinição automática independente de linhas em um lote vetorial assíncrono não é suportada; inicie um novo rollout para que as filas completas de política e de ação sejam redefinidas juntas.

Ações Relativas

Por padrão, o π₀.₅ prevê ações absolutas. Você pode habilitar ações relativas para que o modelo preveja deslocamentos em relação ao estado atual do robô. Isso pode melhorar a estabilidade do treinamento para certas configurações.

Para usar ações relativas, primeiro recalcule as estatísticas do seu conjunto de dados no espaço relativo via CLI:

lerobot-edit-dataset \
    --repo_id your_dataset \
    --new_repo_id your_dataset \
    --operation.type recompute_stats \
    --operation.overwrite true \
    --operation.relative_action true \
    --operation.chunk_size 50 \
    --operation.relative_exclude_joints "['gripper']" \
    --push_to_hub true

Ou, equivalentemente, em Python:

from lerobot.datasets import LeRobotDataset, recompute_stats

dataset = LeRobotDataset("your_dataset")
recompute_stats(dataset, relative_action=True, chunk_size=50, relative_exclude_joints=["gripper"])
dataset.push_to_hub()

O chunk_size deve corresponder ao chunk_size da sua política (padrão 50 para π₀.₅). relative_exclude_joints lista os nomes das juntas que devem permanecer no espaço absoluto (por exemplo, comandos do garra). Use --push_to_hub true para enviar as estatísticas atualizadas para o Hub.

Depois, treine com ações relativas habilitadas:

lerobot-train \
    --dataset.repo_id=your_dataset \
    --policy.type=pi05 \
    --policy.use_relative_actions=true \
    --policy.relative_exclude_joints='["gripper"]' \
    ...

Resultados de Desempenho

Resultados do Benchmark Libero

π₀.₅ demonstrou forte desempenho no conjunto de benchmarks Libero. Para comparar e testar sua implementação no LeRobot, refinamos o modelo base libero por mais 6k passos no conjunto de dados Libero e comparamos os resultados com os resultados de referência do OpenPI.

BenchmarkImplementação do LeRobotReferência do OpenPI
Libero Spatial97.0%98.8%
Objeto Libero99.0%98.2%
Objetivo do Libero98.0%98.0%
Libero 1096.0%92.4%
Média97.5%96.85%

Esses resultados demonstram as fortes capacidades de generalização do π₀.₅ em diversas tarefas de manipulação robótica. Para reproduzir esses resultados, você pode seguir as instruções na seção Libero.

Licença

Este modelo segue a Apache 2.0 License, em conformidade com o repositório original OpenPI.

Update on GitHub