LeRobot documentation

Política π₀.₅ (Pi05)

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

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