Documents : documents
Exemple d'agent robot simple :
Exemple de simulation avec SimplerEnv :
? Agent moteur utilisant OpenVLA :
⏺️ Enregistrer un ensemble de données sur un robot
? Assistance, discussion et procédures :
Mises à jour :
28 août 2024, agents incorporés v1.2
mbodied
pour les essayer.30 juin 2024, agents-incarnés v1.0 :
mbodied
.Embined Agents est une boîte à outils permettant d'intégrer de grands modèles multimodaux dans des piles de robots existantes avec seulement quelques lignes de code. Il offre cohérence, fiabilité, évolutivité et est configurable pour n’importe quel espace d’observation et d’action.
La classe Sample est un modèle de base pour la sérialisation, l'enregistrement et la manipulation de données arbitraires. Il est conçu pour être extensible, flexible et fortement typé. En encapsulant vos objets d'observation ou d'action dans la classe Sample, vous pourrez facilement convertir vers et depuis les éléments suivants :
Pour en savoir plus sur toutes les possibilités des agents incarnés, consultez la documentation
pack
une liste de Sample
ou Dicts dans un seul Sample
ou Dict
et unpack
en conséquence ?unflatten
n'importe quelle structure Python dans une classe Sample
à condition de lui fournir un schéma JSON valide ? La création d'un Sample nécessite simplement d'encapsuler un dictionnaire Python avec la classe Sample
. De plus, ils peuvent être fabriqués à partir de kwargs, d'espaces de gymnastique et de tenseurs, pour n'en nommer que quelques-uns.
from mbodied . types . sample import Sample
# Creating a Sample instance
sample = Sample ( observation = [ 1 , 2 , 3 ], action = [ 4 , 5 , 6 ])
# Flattening the Sample instance
flat_list = sample . flatten ()
print ( flat_list ) # Output: [1, 2, 3, 4, 5, 6]
# Generating a simplified JSON schema
>> > schema = sample . schema ()
{ 'type' : 'object' , 'properties' : { 'observation' : { 'type' : 'array' , 'items' : { 'type' : 'integer' }}, 'action' : { 'type' : 'array' , 'items' : { 'type' : 'integer' }}}}
# Unflattening a list into a Sample instance
Sample . unflatten ( flat_list , schema )
>> > Sample ( observation = [ 1 , 2 , 3 ], action = [ 4 , 5 , 6 ])
La classe Sample exploite les puissantes fonctionnalités de Pydantic pour la sérialisation et la désérialisation, vous permettant de convertir facilement entre les instances Sample et JSON.
# Serialize the Sample instance to JSON
sample = Sample ( observation = [ 1 , 2 , 3 ], action = [ 4 , 5 , 6 ])
json_data = sample . model_dump_json ()
print ( json_data ) # Output: '{"observation": [1, 2, 3], "action": [4, 5, 6]}'
# Deserialize the JSON data back into a Sample instance
json_data = '{"observation": [1, 2, 3], "action": [4, 5, 6]}'
sample = Sample . model_validate ( from_json ( json_data ))
print ( sample ) # Output: Sample(observation=[1, 2, 3], action=[4, 5, 6])
# Converting to a dictionary
sample_dict = sample . to ( "dict" )
print ( sample_dict ) # Output: {'observation': [1, 2, 3], 'action': [4, 5, 6]}
# Converting to a NumPy array
sample_np = sample . to ( "np" )
print ( sample_np ) # Output: array([1, 2, 3, 4, 5, 6])
# Converting to a PyTorch tensor
sample_pt = sample . to ( "pt" )
print ( sample_pt ) # Output: tensor([1, 2, 3, 4, 5, 6])
gym_space = sample . space ()
print ( gym_space )
# Output: Dict('action': Box(-inf, inf, (3,), float64), 'observation': Box(-inf, inf, (3,), float64))
Voir sample.py pour plus de détails.
La classe Message représente un espace échantillon d’achèvement unique. Il peut s'agir de texte, d'image, d'une liste de texte/images, d'un échantillon ou d'une autre modalité. La classe Message est conçue pour gérer différents types de contenu et prend en charge différents rôles tels qu'utilisateur, assistant ou système.
Vous pouvez créer un Message
de diverses manières. Ils peuvent tous être compris par le backend de mbodi.
from mbodied . types . message import Message
Message ( role = "user" , content = "example text" )
Message ( role = "user" , content = [ "example text" , Image ( "example.jpg" ), Image ( "example2.jpg" )])
Message ( role = "user" , content = [ Sample ( "Hello" )])
La classe Backend est une classe de base abstraite pour les implémentations Backend. Il fournit la structure et les méthodes de base requises pour interagir avec différents services backend, tels que les appels API pour générer des complétions basées sur des messages donnés. Consultez le répertoire backend pour savoir comment les différents backends sont implémentés.
Agent est la classe de base pour divers agents répertoriés ci-dessous. Il fournit un modèle pour créer des agents capables de parler à un backend/serveur distant et éventuellement d'enregistrer leurs actions et observations.
L'agent linguistique peut se connecter à différents backends ou transformateurs de votre choix. Il comprend des méthodes pour enregistrer des conversations, gérer le contexte, rechercher des messages, oublier des messages, stocker le contexte et agir sur la base d'une instruction et d'une image.
Prend en charge nativement les services API : OpenAI, Anthropic, vLLM, Ollama, HTTPX ou tout autre point de terminaison gradio. Plus à venir !
Pour utiliser OpenAI pour le backend de votre robot :
from mbodied . agents . language import LanguageAgent
agent = LanguageAgent ( context = "You are a robot agent." , model_src = "openai" )
Pour exécuter une instruction :
instruction = "pick up the fork"
response = robot_agent . act ( instruction , image )
Language Agent peut également se connecter à vLLM. Par exemple, supposons que vous exécutiez un serveur vLLM Mistral-7B sur 1.2.3.4:1234. Tout ce que vous avez à faire est de :
agent = LanguageAgent (
context = context ,
model_src = "openai" ,
model_kwargs = { "api_key" : "EMPTY" , "base_url" : "http://1.2.3.4:1234/v1" },
)
response = agent . act ( "Hello, how are you?" , model = "mistralai/Mistral-7B-Instruct-v0.3" )
Exemple utilisant Ollama :
agent = LanguageAgent (
context = "You are a robot agent." , model_src = "ollama" ,
model_kwargs = { "endpoint" : "http://localhost:11434/api/chat" }
)
response = agent . act ( "Hello, how are you?" , model = "llama3.1" )
Motor Agent est similaire à Language Agent mais au lieu de renvoyer une chaîne, il renvoie toujours un Motion
. Motor Agent est généralement alimenté par des modèles de transformateurs robotiques, c'est-à-dire OpenVLA, RT1, Octo, etc. Certains petits modèles, comme RT1, peuvent fonctionner sur des appareils de périphérie. Cependant, certains, comme OpenVLA, peuvent être difficiles à exécuter sans quantification. Voir l'agent OpenVLA et un exemple de serveur OpenVLA
Ces agents interagissent avec l'environnement pour collecter les données des capteurs. Ils renvoient toujours un SensorReading
, qui peut être diverses formes d'entrées sensorielles traitées telles que des images, des données de profondeur ou des signaux audio.
Actuellement, nous avons :
agents qui traitent les informations des capteurs du robot.
L'agent automatique sélectionne et initialise dynamiquement l'agent approprié en fonction de la tâche et du modèle.
from mbodied . agents . auto . auto_agent import AutoAgent
# This makes it a LanguageAgent
agent = AutoAgent ( task = "language" , model_src = "openai" )
response = agent . act ( "What is the capital of France?" )
# This makes it a motor agent: OpenVlaAgent
auto_agent = AutoAgent ( task = "motion-openvla" , model_src = "https://api.mbodi.ai/community-models/" )
action = auto_agent . act ( "move hand forward" , Image ( size = ( 224 , 224 )))
# This makes it a sensory agent: DepthEstimationAgent
auto_agent = AutoAgent ( task = "sense-depth-estimation" , model_src = "https://api.mbodi.ai/sense/" )
depth = auto_agent . act ( image = Image ( size = ( 224 , 224 )))
Vous pouvez également utiliser la méthode get_agent
dans auto_agent.
language_agent = get_agent ( task = "language" , model_src = "openai" )
Le module motion_controls définit divers mouvements pour contrôler un robot sous forme de modèles Pydantic. Ils sont également sous-classés de Sample
, possédant ainsi toutes les capacités de Sample
comme mentionné ci-dessus. Ces commandes couvrent une gamme d'actions, allant des simples mouvements articulaires aux poses complexes et au contrôle complet du robot.
Vous pouvez intégrer votre matériel robot personnalisé en sous-classant Robot assez facilement. Il vous suffit d'implémenter la fonction do()
pour effectuer des actions (et quelques méthodes supplémentaires si vous souhaitez enregistrer un ensemble de données sur le robot). Dans nos exemples, nous utilisons un robot fictif. Nous avons également un robot XArm comme exemple.
Enregistrer un jeu de données sur un robot est très simple ! Tout ce que vous avez à faire est d’implémenter les méthodes get_observation()
, get_state()
et prepare_action()
pour votre robot. Après cela, vous pouvez enregistrer un ensemble de données sur votre robot à tout moment. Voir examples/5_teach_robot_record_dataset.py et cette collaboration : pour plus de détails.
from mbodied . robots import SimRobot
from mbodied . types . motion . control import HandControl , Pose
robot = SimRobot ()
robot . init_recorder ( frequency_hz = 5 )
with robot . record ( "pick up the fork" ):
motion = HandControl ( pose = Pose ( x = 0.1 , y = 0.2 , z = 0.3 , roll = 0.1 , pitch = 0.2 , yaw = 0.3 ))
robot . do ( motion )
Dataset Recorder est un enregistreur de niveau inférieur pour enregistrer votre conversation et les actions du robot dans un ensemble de données pendant que vous interagissez avec/apprenez au robot. Vous pouvez définir n’importe quel espace d’observation et espace d’action pour l’enregistreur. Voir gymnase pour plus de détails sur les espaces.
from mbodied . data . recording import Recorder
from mbodied . types . motion . control import HandControl
from mbodied . types . sense . vision import Image
from gymnasium import spaces
observation_space = spaces . Dict ({
'image' : Image ( size = ( 224 , 224 )). space (),
'instruction' : spaces . Text ( 1000 )
})
action_space = HandControl (). space ()
recorder = Recorder ( 'example_recorder' , out_dir = 'saved_datasets' , observation_space = observation_space , action_space = action_space )
# Every time robot makes a conversation or performs an action:
recorder . record ( observation = { 'image' : image , 'instruction' : instruction ,}, action = hand_control )
L'ensemble de données est enregistré dans ./saved_datasets
.
La classe Replayer est conçue pour traiter et gérer les données stockées dans les fichiers HDF5 générés par Recorder
. Il fournit une variété de fonctionnalités, notamment la lecture d'échantillons, la génération de statistiques, l'extraction d'éléments uniques et la conversion d'ensembles de données à utiliser avec HuggingFace. Le Replayer prend également en charge l'enregistrement d'images spécifiques pendant le traitement et offre une interface de ligne de commande pour diverses opérations.
Exemple d'itération dans un ensemble de données de Recorder avec Replayer :
from mbodied . data . replaying import Replayer
replayer = Replayer ( path = str ( "path/to/dataset.h5" ))
for observation , action in replayer :
...
├─ assets/ ............. Images, icons, and other static assets
├─ examples/ ........... Example scripts and usage demonstrations
├─ resources/ .......... Additional resources for examples
├─ src/
│ └─ mbodied/
│ ├─ agents/ ....... Modules for robot agents
│ │ ├─ backends/ .. Backend implementations for different services for agents
│ │ ├─ language/ .. Language based agents modules
│ │ ├─ motion/ .... Motion based agents modules
│ │ └─ sense/ ..... Sensory, e.g. audio, processing modules
│ ├─ data/ ......... Data handling and processing
│ ├─ hardware/ ..... Hardware modules, i.e. camera
│ ├─ robot/ ........ Robot interface and interaction
│ └─ types/ ........ Common types and definitions
└─ tests/ .............. Unit tests
Nous acceptons les problèmes, les questions et les relations publiques. Consultez le guide de contribution pour plus d’informations.