Strands Robots fecha o ciclo de robótica gravando, treinando e implantando no mesmo formato
AWS e Hugging Face integram Strands Agents, LeRobot e os novos Storage Buckets para rodar o loop de dados de robótica embodied sem downloads repetidos nem conversão de formato.

A robótica embodied vive um problema chato de encanamento: quem coleta demonstrações, treina uma política e implanta de volta no braço acaba pagando pela mesma transferência de bytes várias vezes por dia. Cada rodada de gravação cresce, cada treino copia o dataset inteiro para as GPUs antes de começar, e cada checkpoint novo sobe enquanto o próximo lote de gravações desce. O post da Hugging Face que serve de fonte aqui (Record, train, and deploy from one place) mostra como a AWS↳AWS20 conteúdosE-mails de verificação com AWS SES + Lambda (Node.js) e Terraform: do zero ao envioDevSecOps · out 2025Codex na AWS: chegada do agente da OpenAI à nuvem da AmazonDevSecOps · abr 2026Salesforce e AWS ampliam colaboração em IA, CRM e marketplaceDevSecOps · nov 2023Ver tudo em DevSecOps → e a HF costuraram um fluxo único para atacar exatamente esse custo.
A peça central é o Strands Robots, um SDK open source↳Open source71 conteúdosComo o Open Source Está Liberando o Poder da Automação para TodosDev (Back & Front) · out 2025Código aberto: programadores criam software da NASA sem saberDev (Back & Front) · abr 2021N8N: O que é a ferramenta open source que está revolucionando a automação em TI?Dev (Back & Front) · dez 2025Ver tudo em Dev (Back & Front) → (Apache 2.0) da AWS que expõe abstrações de robô, simulação e a stack do LeRobot como AgentTools que você compõe em um único agente Strands. O ponto que importa: um mesmo objeto Robot() grava o dataset e o lê de volta. Coletar dados e treinar viram dois métodos sobre o mesmo backend, no mesmo formato de disco do LeRobot do começo ao fim, sem conversão.
O loop inteiro em poucas linhas
O exemplo mínimo da fonte roda num laptop, com o caminho padrão de simulação:
from strands import Agent
from strands_robots import Robot
sim = Robot("so100") # mode="sim" (default, sem hardware)
agent = Agent(tools=[sim])
# Grava uma demonstração e sincroniza para um bucket.
agent("Record a pick-the-cube demo and sync it to my-org/robot-fave.")
# Faz streaming de volta do bucket para treinar, sem baixar antes.
for batch in sim.stream_dataset("my-org/robot-fave/cube_pick", repo_type="bucket").dataloader(batch_size=64):
...Vale um aviso honesto que a própria fonte faz: o caminho padrão usa uma mock policy, que gera ações de junta sem modelo treinado. Ou seja, ele grava um dataset estruturalmente válido, mas não útil para treino de verdade. O objetivo é rodar o loop ponta a ponta antes de ter um checkpoint. Para grasping real, troca-se pela create_policy("") e o resto (prompt, formato, sync) fica idêntico.
O que os Storage Buckets resolvem
O ingrediente novo é o Storage Bucket, um tipo de repositório de object storage mutável, não versionado e backed por Xet, anunciado pela HF em março de 2026. Ele vive no mesmo namespace hf://, ao lado dos seus datasets, e usa o hf CLI e as permissões que você já tem. Sem IAM, sem regras de CORS, sem serviço de upload para manter.
A distinção conceitual é o que faz sentido. Um repositório de dataset versionado retém cada revisão: mudar um frame num shard de vídeo de vários gigabytes re-sobe o arquivo inteiro e cada append vira commit. Coleta contínua quer o oposto: um lugar para escrever bytes e sobrescrever no lugar. O bucket é essa camada de trabalho. Para o artefato publicado e versionado, você continua chamando push_to_hub(). Ambos guardam o mesmo formato.
from strands_robots import sync_dataset_to_bucket
sync_dataset_to_bucket("/tmp/cube_pick", "my-org/robot-fave")
# -> {"status": "success", "bucket_uri": "hf://buckets/my-org/robot-fave/cube_pick"}Deduplicação por byte muda a conta do dia a dia
Aqui está o argumento técnico mais concreto. Aponte duas câmeras fixas para um braço limpando a mesma mesa por oito horas e a maior parte do que você grava são pixels que já existem: mesma iluminação, mesmo chassi, mesmo fundo, em milhares de episódios.
Os buckets usam Xet com content-defined chunking: as fronteiras de chunk seguem o conteúdo, então inserir alguns bytes altera só o chunk onde eles caem, sem deslocar todas as fronteiras seguintes. Nas medições da própria HF, isso reduz os dados transferidos por upload em cerca de quatro vezes no Hub, e em planos Enterprise a cobrança é sobre o footprint deduplicado. Os benchmarks de bucket dão números diretos: partindo de um upload de 500 MB, mudar 1% dos bytes e re-subir moveu 5,5 MB; mudar 5% moveu 27,5 MB; mudar 10% moveu 55 MB. Sem deduplicação em nível de chunk, sobrescrever um objeto significa mandar todos os bytes de novo.
O layout de arquivo do LeRobot amplifica isso. Episódios vão para shards Parquet (data/chunk-000/file-000.parquet) e MP4 por câmera, rolando para um arquivo novo só quando o atual enche, nos defaults de 100 MB para Parquet e 200 MB para vídeo. Então um sync depois de um dia de gravação sobe os shards finais novos mais o único shard parcial que cresceu, não o dataset inteiro.
Treinar por streaming, sem esperar o download
Baixar o dataset primeiro deixa as GPUs ociosas até centenas de gigabytes terminarem de copiar. O streaming funciona aqui justamente por causa do layout de shards: um batch vira algumas leituras de byte-range sobre shards grandes, em vez de milhares de fetches pequenos. O StreamingLeRobotDataset do LeRobot é um iterável torch drop-in, exposto via stream_dataset():
reader = sim.stream_dataset("my-org/robot-fave/cube_pick", repo_type="bucket",
shuffle=False, max_num_shards=1, buffer_size=1)
for frame in reader:
frame["observation.images.front"] # tensor (3, H, W), decodificado do MP4 na hora
frame["observation.state"] # vetor de junta, do Parquet
frame["action"]
breakNada cai no disco local exceto a pequena pasta meta/ de schema, estatísticas e índice de episódios. Quem prefere não escrever o loop pode usar o lerobot-train diretamente, com uma restrição importante: buckets são streaming-only, então --dataset.repo_type=bucket exige --dataset.streaming=true, e a config rejeita a combinação caso contrário.
Para borda sem torchcodec, drop_videos=True pula a decodificação de vídeo por completo (streaming só proprioceptivo). E há um número medido para ancorar expectativas: numa única NVIDIA L4 (g6.4xlarge), 500 passos de otimização de ACT (51,6M de parâmetros, batch efetivo 8) sobre um episódio de 120 frames levaram 133 segundos. A fonte é explícita em tratar isso como uma configuração medida, não um benchmark: o tempo escala com tamanho do dataset, batch e número de passos.
Deploy e a volta ao início
A implantação é o ponto onde o desenho compensa: é o mesmo código de agente, com um argumento trocado para mode="real".
robot = Robot("so100", mode="real", port="/dev/ttyACM0",
cameras={"front": {"type": "opencv", "index_or_path": "/dev/video0", "fps": 30}})
agent = Agent(tools=[robot])
agent("Pick up the red cube.")O checkpoint roda contra o braço físico e as demonstrações que ele grava saem no mesmo formato LeRobot, prontas para sincronizar de volta ao bucket para o próximo treino. O loop fecha.
Onde isso importa (e onde não vale)
Para o dev brasileiro, o ganho prático é reduzir encanamento: quem já mexe com LeRobot ganha uma rota Hub-native para sync e streaming sem provisionar storage nem configurar IAM/CORS. Um detalhe regional a observar: a escolha de onde os dados ficam é uma configuração de Storage Regions disponível nos planos Team e Enterprise, hoje US e EU (com Ásia-Pacífico e GCC anunciadas como futuras). Fora desses planos, os repositórios ficam nos EUA, o que tem implicações de latência e de conformidade de dados para quem opera daqui.
A fonte também é justa em apontar o caminho alternativo: se seus dados já vivem no Amazon S3, nada do trabalho de formato muda, porque um LeRobotDataset é só um diretório de shards Parquet e MP4. O bucket não substitui o S3; ele oferece a rota hf:// direta com o sync e o streaming embutidos. Se você já tem pipeline de storage montado e otimizado, o benefício marginal do bucket é menor. Ele brilha para quem quer o loop rodando rápido sem montar infraestrutura de armazenamento primeiro. E, como sempre, o caminho padrão em simulação com mock policy serve para validar o encanamento, não para produzir política treinável: sem GPU e sem lerobot[training], trainer.train() devolve erro em vez de checkpoint.
Fonte: Hugging Face Blog
Este artigo foi escrito por Alan Andrade, colunista de inteligência artificial do iMasters, um agente de inteligência artificial com revisão editorial humana.









