LeRobot documentation
Columnas de idioma y recetas
Columnas de idioma y recetas
La mayoría de los conjuntos de datos de LeRobot incluyen una única cadena task por episodio, lo cual es suficiente para habilidades cortas con una sola instrucción, pero no es suficiente para las políticas de robots de horizonte más largo y multimodales hacia las que se dirige el campo (planificación de alto nivel, memoria, interrupciones, VQA, uso de herramientas). Para admitir esas políticas sin bifurcar el formato del conjunto de datos, LeRobot extiende LeRobotDataset con dos columnas de lenguaje opcionales y una pequeña capa de receta que convierte esas filas en muestras de entrenamiento estilo chat al vuelo.
El diseño se divide claramente en tres capas:
- Datos en el conjunto de datos — anotaciones de idioma almacenadas junto a los fotogramas en
data/chunk-*/file-*.parquetcomo dos columnas opcionales (language_persistentylanguage_events). Los conjuntos de datos sin estas columnas mantienen su comportamiento existente. - Receta — un archivo YAML que declara qué filas de anotación vincular y cómo distribuirlas como turnos de chat (
role,content, imágenes opcionales, llamadas a herramientas opcionales). Las recetas son configuración pura; no se requiere Python para añadir una nueva. - Formato de entrenamiento — en el momento de la muestra,
RenderTrainingMessagesStepresuelve la receta frente a las anotaciones por cuadro y emitemessagesen estilo HF junto con archivos secundarios específicos de LeRobot (message_streams,target_message_indices) que los procesadores de política consumen.
Esta página describe cada capa por separado.
Capa 1 — columnas de idioma en el conjunto de datos
Las dos columnas opcionales se encuentran junto a los datos de fotogramas en data/chunk-*/file-*.parquet:
language_persistent: una lista de filas que se difunde en cada fotograma de un episodio para el estado que permanece activo, comosubtask,planymemory.language_events: una lista de filas solo en el fotograma exacto en el que se emitió un evento, comointerjection,vqay llamadas a herramientas de voz.
Ambas columnas comparten la misma forma de fila (las filas de eventos omiten timestamp porque el cuadro en el que se encuentra la fila ya lo proporciona):
role: string content: string | null style: string | null timestamp: float32 # persistent rows only camera: string | null # observation.images.* feature key, view-dependent rows only tool_calls: list[Json] | null
El campo camera marca las filas cuyo content se basa en una vista de cámara específica. Las filas de estilos dependientes de la vista (vqa y trace) DEBEN establecer camera con la clave de característica correspondiente de observation.images.*. Las filas de cualquier otro estilo, incluido motion, que describe primitivas del marco del robot en términos articulares / cartesianos, DEBEN dejar camera como null. Los escritores de la pipeline y el validador aplican esto mediante validate_camera_field(style, camera).
meta/tasks.parquet sigue siendo la fuente canónica de la tarea. La especial receta de enlace ${task} siempre lee esa cadena de tarea y no depende de las anotaciones de idioma.
Arquitectura
El propio stack de lenguaje tiene tres módulos internos que respaldan la capa 1:
lerobot.datasets.languagedefine el esquema, el registro de estilos ycolumn_for_style.lerobot.datasets.language_renderresuelve filas y renderiza mensajes.RenderTrainingMessagesStepconvierte las muestras del conjunto de datos enmessages,message_streamsytarget_message_indices.
LeRobotDataset es agnóstico a las recetas. Transmite language_persistent y language_events cuando están presentes, y los conjuntos de datos sin anotaciones mantienen su comportamiento existente.
Capa 2 — anatomía de la receta
Las recetas son archivos YAML respaldados por TrainingRecipe y MessageTurn de lerobot.datasets.recipe. Declaran qué filas de anotación extraer (mediante bindings) y cómo componerlas en turnos de chat (messages).
messages:
- { role: user, content: "${task}", stream: high_level }
- { role: assistant, content: "${subtask}", stream: low_level, target: true }Una receta también puede ramificarse en una mezcla ponderada de subrecetas. En el momento de la muestreo, se selecciona exactamente una rama de forma determinista a partir del índice de la muestra, de modo que distintos fotogramas entrenan distintos objetivos (p. ej., actualizaciones de memoria frente a ejecución de bajo nivel frente a VQA) sin ningún cableado en Python.
Semántica temporal
Los estilos persistentes están activos después de la emisión hasta que se reemplazan:
active_at(t, style=subtask)nth_prev(style=memory, offset=1)nth_next(style=subtask, offset=1)
Los estilos de eventos solo existen en su marca de tiempo exacta:
emitted_at(t, style=interjection)emitted_at(t, style=vqa, role=user, camera=observation.images.top)emitted_at(t, role=assistant, tool_name=say)
La coincidencia exacta de eventos no tiene una ventana de tolerancia, por lo que los escritores deben sellar las filas de eventos con las marcas de tiempo de los fotogramas de los datos de parquet.
Resolución dependiente de la vista
Para los estilos dependientes de la vista (vqa y trace), el resolver incorpora un filtro camera= paralelo a role= y tool_name=. Los conjuntos de datos con múltiples cámaras suelen emitir un par (vqa, user) + (vqa, assistant) por cámara en el mismo sello de tiempo; sin camera=, esos resolvers detectan dos coincidencias y lanzan un error de ambigüedad. Las recetas consumen cada cámara a través de su propia vinculación junto con un bloque de imagen correspondiente, por ejemplo:
ask_vqa_top:
route: vqa
bindings:
vqa_query: "emitted_at(t, style=vqa, role=user, camera=observation.images.top)"
vqa: "emitted_at(t, style=vqa, role=assistant, camera=observation.images.top)"
messages:
- role: user
stream: high_level
if_present: vqa_query
content:
- { type: image, feature: observation.images.top }
- { type: text, text: "${vqa_query}" }
- {
role: assistant,
content: "${vqa}",
stream: high_level,
target: true,
if_present: vqa,
}Añada una subreceta de este tipo por cada cámara que registre el conjunto de datos. El marcador explícito route: vqa hace que una anotación VQA dispersa coincidente tenga prioridad sobre la selección de mezcla ponderada normal; los nombres de los componentes son puramente descriptivos.
Capa 3 — formato de entrenamiento
Las muestras renderizadas utilizan mensajes de chat en el estilo de HF junto con sidecars de LeRobot:
sample["messages"]
sample["message_streams"]
sample["target_message_indices"]El renderer no aplica una plantilla de chat del tokenizer. Los procesadores de política deciden cómo serializar los mensajes para su backbone, lo que mantiene el mismo dataset utilizable en SmolVLA, Pi0.5 y cualquier VLM futuro que espere mensajes de chat en estilo OpenAI.
Mezclas
Las recetas de mezcla seleccionan de forma determinista una subreceta ponderada a partir del índice de la muestra. recipes/subtask_mem.yaml entrena la mezcla compacta del núcleo: predicción de subtareas de alto nivel, ejecución de bajo nivel y memoria. recipes/subtask_mem_vqa_speech.yaml es la variante más completa, que además añade respuestas de VQA y de interrupciones habladas.
recipes/subtask_joint.yaml demuestra el entrenamiento conjunto de secuencias en lugar de una mezcla ponderada. Para la misma muestra, su subtarea de asistente se supervisa con entropía cruzada de texto en el flujo low_level mientras la predicción de acciones permanece activa, coincidiendo con la configuración conjunta del paper de π0.5. Por ahora es solo para entrenamiento: el runtime aún no reconstruye este prefijo conjunto en la inferencia.
Ausencia elegante
Si ambas columnas de idioma faltan, son None o están vacías, RenderTrainingMessagesStep utiliza la cadena de tarea como supervisión de bajo nivel cuando está disponible y, en caso contrario, deja la muestra sin cambios. Para una muestra anotada, si ninguna rama de receta se aplica y no existe una tarea de respaldo, la renderización devuelve None, lo que permite que un loader reintente con otra muestra.