LeRobot documentation
VLA-JEPA
VLA-JEPA
Esta é a portação do LeRobot para o VLA-JEPA, um modelo Vision-Language-Action que combina um backbone de linguagem Qwen3-VL com um modelo de mundo de vídeo auto-supervisionado (V-JEPA2) e uma cabeça de ação flow-matching DiT.
Visão geral da arquitetura
O VLA-JEPA possui três componentes principais:
| Componente | Módulo | Função |
|---|---|---|
| Backbone Qwen3-VL | Qwen3VLInterface | Funde imagens + instrução de linguagem em tokens de contexto |
| Cabeça de ação DiT-B | VLAJEPAActionHead | Difusão de correspondência de fluxo sobre o trecho de ação |
| Modelo de mundo V-JEPA2 | ActionConditionedVideoPredictor | Perda de previsão de vídeo auto-supervisionada (apenas treinamento) |
Fluxo de dados
Treinamento:
- Um clipe de vídeo de
num_video_framesquadros é codificado pelo V-JEPA2 em tokens de patch por quadro. - O backbone Qwen3-VL processa imagens multiview + a instrução da tarefa e produz uma sequência de tokens de contexto que inclui tokens de ação especiais (para condicionamento do modelo de mundo) e tokens corporificados.
- A cabeça de ação recebe esses tokens de contexto como chaves/valores de atenção cruzada e prevê um trecho de ação desruído por meio de correspondência de fluxo.
- O preditor do modelo de mundo usa os tokens de ação extraídos do Qwen para prever os embeddings de quadros futuros do V-JEPA2; uma perda de regressão sobre essas previsões é adicionada à perda de ação.
Inferência: Apenas o Qwen e a cabeça de ação são usados. O modelo de mundo não é necessário no momento da inferência.
Detalhes da cabeça de ação
Predefinições disponíveis via action_model_type:
| Pré-definido | Cabeças | Dimensão da cabeça |
|---|---|---|
DiT-B | 12 | 64 |
DiT-L | 32 | 48 |
O preset define apenas a geometria de atenção, e cada entrada pode ser sobrescrita por action_num_heads / action_attention_head_dim. Duas larguras derivam dele:
- a largura interna do DiT é
heads x head_dim(768 paraDiT-B), derivada e não configurada; - a largura da saída do DiT, bem como a largura dos MLPs do decodificador de ação e do codificador de estado, é
action_hidden_size(padrão 1024).
Portanto, o DiT-B executa um transformer de largura 768 que projeta para 1024. Os dois são independentes.
Detalhes do modelo de mundo
O preditor de vídeo é um transformer no estilo ViT (ActionConditionedVideoPredictor) que recebe:
- Tokens de quadro: incorporações de patch do V-JEPA2 projetadas para
predictor_embed_dim - Tokens de ação: incorporações de tokens de ação do Qwen projetadas para
predictor_embed_dim
Ele usa atenção causal por bloco, de modo que cada passo temporal pode prestar atenção a todos os passos anteriores. A entrada do preditor embed_dim é igual a num_views × video_encoder_hidden_size (por exemplo, 2 views × 1024 = 2048 para os checkpoints pré-treinados).
Pontos de Verificação Pré-treinados
Três checkpoints estão disponíveis diretamente dentro da organização LeRobot aqui: lerobot/VLA-JEPA, convertidos de ginwind/VLA-JEPA:
| Checkpoint | Conjunto de dados | Câmeras | Modelo de mundo | Dimensão da ação |
|---|---|---|---|---|
lerobot/VLA-JEPA-LIBERO | LIBERO-10 | 2 (agentview + pulso) | Ativado | 7 |
lerobot/VLA-JEPA-Pretrain | DROID 1.0.1 | 2 (visões externas à esquerda) | Ativado | 7 |
lerobot/VLA-JEPA-SimplerEnv | OXE Bridge / RT-1 | 1 (visualização duplicada ×2) | Ativado | 7 |
Todos os checkpoints usam Qwen/Qwen3-VL-2B-Instruct como a base de linguagem.
Configuração
Principais parâmetros em VLAJEPAConfig:
| Parâmetro | Padrão | Descrição |
|---|---|---|
chunk_size | 7 | Número de ações previstas por chamada de inferência |
n_action_steps | 7 | Etapas executadas a partir do bloco previsto antes do replanejamento |
num_video_frames | 8 | Comprimento do clipe de vídeo enviado ao modelo de mundo |
enable_world_model | True | Se deve carregar e treinar o preditor V-JEPA2 |
world_model_loss_weight | 0.1 | Peso da perda de previsão do JEPA em relação à perda de ação |
causal_world_model_context | False | Codifique o contexto do modelo de mundo de forma causal (uma única passagem do V-JEPA2 apenas com prefixo por posição de contexto) para que a atenção bidirecional não vaze quadros futuros para a entrada do preditor. Isso custa t_enc_ctx chamadas extras ao codificador |
num_inference_timesteps | 4 | Etapas de integração de Euler para a remoção de ruído da ação |
freeze_qwen | False | Congele o backbone do Qwen3-VL e treine apenas o action head |
reinit_modules | None | Prefixos de chaves permitidos para serem re-inicializados aleatoriamente no carregamento (para transferência entre diferentes embodiments, veja Fine-tuning em um embodiment diferente) |
resize_images_to | None | (height, width) é o tamanho para o qual cada quadro da câmera é redimensionado antes de ser enviado à torre de visão do Qwen3-VL. None mantém a resolução nativa, e a contagem de patches do Qwen3-VL aumenta com ela, de modo que uma câmera de 720x1280 pode esgotar a memória da GPU. Os checkpoints publicados usam [224, 224] |
gripper_dim | 6 | Índice da dimensão do garra no vetor de ação. Ignorado quando gripper_joint_names corresponde a um nome de ação do conjunto de dados |
gripper_joint_names | ["gripper"] | Nomes das dimensões de ação que identificam a garra; o índice correspondente tem prioridade sobre gripper_dim |
gripper_threshold | 0.5 | Limiar usado por pre_snap_gripper_action e binarize_gripper_action. Observe que binarize é executado após a desnormalização, portanto, este valor é comparado ao valor físico da garra |
pre_snap_gripper_action | False | Ajuste a dimensão do garfo para {0, 1} antes da desnornormalização. Específico do LIBERO, veja abaixo |
binarize_gripper_action | False | Binarize o dim do gripper para {-1, 1} após a desnormalização. Específico do LIBERO, veja abaixo |
clip_normalized_actions | True | Clip as ações normalizadas para [-1, 1] antes de desnormalizá-las. Aplicado apenas quando ACTION usa MIN_MAX; ignorado (com um aviso) sob MEAN_STD, onde truncaria em 1 sigma |
world_model_num_views | None | Visão da câmera para a qual o preditor do modelo de mundo é construído. Incorporada às formas do checkpoint. None usa jepa_tubelet_size como padrão, que é o que os checkpoints publicados codificam |
pre_snap_gripper_actionebinarize_gripper_actionsão uma port do loop de avaliação LIBERO do starVLA e estão corretos apenas para a convenção de ação do LIBERO.pre_snapescreve {0, 1} no espaço normalizado, o desnormalizador mapeia esses valores para o ponto médio e o máximo, ebinarizeentão compara esse valor físico comgripper_threshold(0,5). Para um gripper medido em graus, mm ou [0, 100], ambos os valores ficam acima do limiar e o gripper comandado se torna constante. Por esse motivo, eles têm valor padrãoFalse; habilite-os apenas para configurações no estilo LIBERO e definagripper_thresholdnas próprias unidades do gripper, se for o caso. A fábrica de processadores emite um aviso quando as estatísticas do conjunto de dados mostram que a faixa não pode funcionar.
Treinamento
O número de etapas de treinamento pode variar com base no tamanho do conjunto de dados e no orçamento de computação. O artigo original pré-treinou por 50k em ssv2 + droid conjuntamente, seguido de 30k etapas adicionais para LIBERO, mas menos etapas ainda podem resultar em bom desempenho ao fazer fine-tuning a partir dos checkpoints pré-treinados fornecidos.
Treinamento completo do zero
lerobot-train \ --policy.type=vla_jepa \ --policy.repo_id=your_org/your_repo \ --dataset.repo_id=your_org/your_dataset
Ajuste fino a partir de um checkpoint pré-treinado
lerobot-train \ --policy.path=lerobot/VLA-JEPA-Pretrain \ --policy.repo_id=your_org/your_repo \ --dataset.repo_id=your_org/your_dataset
Se você deseja congelar o backbone do Qwen e treinar apenas a cabeça de ação, defina policy.freeze_qwen=True:
lerobot-train \
--policy.path=lerobot/VLA-JEPA-Pretrain \
--policy.repo_id=your_org/your_repo \
--policy.freeze_qwen=true \
--dataset.repo_id=your_org/your_datasetFine-tuning em uma encarnação diferente
Quando o robô de destino possui uma dimensionalidade de ação ou estado diferente da do checkpoint pré-treinado, as camadas de projeção de entrada/saída da cabeça de ação terão formatos incompatíveis e não poderão ser carregadas diretamente. reinit_modules permite listar os prefixos de chaves que são permitidos para apresentar incompatibilidade — essas camadas são re-inicializadas aleatoriamente, enquanto todos os outros pesos são reutilizados do checkpoint. Qualquer incompatibilidade de formato fora dos prefixos listados gera um erro.
As camadas que dependem de action_dim e state_dim são:
| Camada | Prefixo de chave |
|---|---|
| Codificador de ação (action_dim → inner_dim) | model.action_model.action_encoder |
| Decodificador de ação (hidden_size → action_dim) | model.action_model.action_decoder |
| Codificador de estado (state_dim → inner_dim) | model.action_model.state_encoder |
lerobot-train \
--policy.path=lerobot/VLA-JEPA-Pretrain \
--policy.repo_id=your_org/your_repo \
--policy.freeze_qwen=true \
--policy.reinit_modules='["model.action_model.action_encoder", "model.action_model.action_decoder", "model.action_model.state_encoder"]' \
--dataset.repo_id=your_org/your_datasetSe o seu robô não possui estado proprioceptivo, omita model.action_model.state_encoder da lista.
Reproduzindo os resultados do LIBERO
Treinamento no LIBERO: inicia o treinamento a partir do checkpoint de Pretrain e treina por 30k passos no conjunto de dados LIBERO. O artigo original menciona treinamento em 8 GPUs com um batch size de 32, o que significa um batch size global de 256.
lerobot-train \ --policy.path=lerobot/VLA-JEPA-Pretrain \ --policy.repo_id=your_org/your_repo \ --dataset.repo_id=HuggingFaceVLA/libero \ --steps=30000
Avaliando o checkpoint pré-treinado LIBERO-10:
lerobot-eval \ --policy.path=lerobot/VLA-JEPA-LIBERO \ --env.type=libero \ --env.task=libero_spatial,libero_object,libero_goal,libero_10 \ --eval.n_episodes=10 \ --eval.batch_size=5
Para avaliar apenas um subconjunto de tarefas:
lerobot-eval \
--policy.path=lerobot/VLA-JEPA-LIBERO \
--env.type=libero \
--env.task=libero_10 \
--env.task_ids='[0,1,2]' \
--eval.n_episodes=10 \
--eval.batch_size=5Resultados esperados:
| Suite | Episódios | Sucessos | Taxa de Sucesso |
|---|---|---|---|
| libero_spatial | 100 | 93 | 95.0% |
| libero_object | 100 | 100 | 100.0% |
| libero_goal | 100 | 98 | 98.0% |
| libero_10 | 100 | 96 | 93.0% |
| Geral | 400 | 387 | 96.5% |
Fine-tuning em conjuntos de dados com um número diferente de câmeras
O preditor do modelo de mundo pré-treinado foi treinado com embed_dim = world_model_num_views × 1024, ou seja, duas vistas de câmera.
Essa contagem de visualizações era lida de
jepa_tubelet_size, que também nomeia o tamanho do tubelet temporal do codificador JEPA.world_model_num_viewsé o campo para isso agora; deixá-lo emNonefaz com que ele volte parajepa_tubelet_size, de modo que os checkpoints publicados continuem sendo carregados sem alterações.
Comportamento padrão — visualização de preenchimento/trimming (nenhuma ação necessária)
Ao fazer o ajuste fino a partir de VLA-JEPA-Pretrain, o modelo ajusta automaticamente o número de visualizações fornecidas ao modelo de mundo para corresponder a world_model_num_views:
- Conjuntos de dados de visão única (por exemplo, BridgeV2): o latente de visão única é duplicado para produzir uma entrada de modelo de mundo de duas visões, preservando o sinal autorregressivo do JEPA sem qualquer incompatibilidade de pesos.
- >Conjuntos de dados com mais de 2 vistas (por exemplo, DROID com 3 vistas): todas as vistas são passadas para o backbone Qwen (para um contexto mais rico), mas apenas as primeiras
world_model_num_viewsvistas (um pulso + uma terceira pessoa, seguindo a ordem de vista configurada) são usadas para o modelo de mundo.
Opção 1 — Desativar o modelo de mundo
Defina enable_world_model=False para ignorar completamente a perda JEPA. Somente o backbone Qwen e a cabeça de ação são carregados e treinados. Isso é suficiente para um bom desempenho de ação.
lerobot-train \
--policy.path=lerobot/VLA-JEPA-Pretrain \
--policy.enable_world_model=false \
--policy.repo_id=your_org/your_repo \
--dataset.repo_id=your_org/single_camera_datasetOpção 2 — Reinitializar a projeção de entrada do predictor
Se você quiser alterar world_model_num_views para um valor diferente de 2, carregue o checkpoint com strict=False e reinitialize model.video_predictor.predictor_embed para o novo embed_dim. Todos os outros pesos dos blocos do preditor (atenção, MLP, norm, projeção de saída) são independentes do número de câmeras e podem ser reutilizados a partir do checkpoint pré-treinado.
Citação
@misc{sun2026vlajepaenhancingvisionlanguageactionmodel,
title = {VLA-JEPA: Enhancing Vision-Language-Action Model with Latent World Model},
author = {Jingwen Sun and Wenyao Zhang and Zekun Qi and Shaojie Ren and Zezhi Liu and Hanxin Zhu and Guangzhong Sun and Xin Jin and Zhibo Chen},
year = {2026},
eprint = {2602.10098},
archivePrefix = {arXiv},
primaryClass = {cs.RO},
url = {https://arxiv.org/abs/2602.10098},
}Licença
Os pesos são distribuídos sob os termos de licença do repositório original ginwind/VLA-JEPA (Apache 2.0 License). O código de integração do LeRobot segue a Apache 2.0 License.
Update on GitHub