LeRobot documentation

Bir Politika Ekleme

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

Bir Politika Ekleme

Bu kılavuz, özel bir politika uygulamanızı ve LeRobot'un eğitim, değerlendirme ve dağıtım araçlarıyla çalışmasını sağlamanızı adım adım anlatır. İki yol vardır:

  • Eklenti (ağaç dışı) — politikayı bağımsız bir lerobot_policy_* paketi olarak dağıtın. Daha hızlıdır, PR gerektirmez, hızlıca geliştirme yapmanızı sağlar. Deneyler, dahili kullanım veya bağımsız olarak yayınlamak istediğiniz durumlar için uygundur.
  • Ağaç içi (LeRobot'a katkı sağlandı) — politikanızı doğrudan src/lerobot/policies/ dizinine ekleyin. Bir PR gerektirir, ancak politikanız kütüphanenin birinci sınıf bir vatandaşı haline gelir.

Eklenti yolu genellikle doğru başlangıç noktasıdır — politika istikrara kavuştuğunda ve kütüphaneyle birlikte dağıtmanın açık bir değeri olduğunda, ağaç içine (in-tree) yükseltin.

Her iki durumda da yapı taşları aynıdır: bir yapılandırma sınıfı, bir politika sınıfı ve bir işlemci fabrikası. Bu kılavuzun ilk yarısı bu ortak parçaları; ikinci yarısı ise yol bazlı iskeleti (Path A, Path B) ele alır.

Ton hakkında bir not: robot-learning aktif olarak gelişen bir alandır ve “bir politikanın nasıl göründüğü” her yeni mimariyle değişebilir. Burada açıklanan kurallar, lerobot-train ve lerobot-eval'in çok farklı modeller arasında tutarlı bir şekilde çalışmasını sağladığı için mevcuttur. Yeni bir politika gerçekten bu kurallara uymuyorsa bunu bildirin (PR'ınızda veya bir issue'da) — kurallar kutsal değildir.


Bir politikanın anatomisi

Her politika üç yapı taşından oluşur. Aşağıdaki isimler my_policy adını bir yer tutucu olarak kullanır — kendi politikanızın adıyla değiştirin. Bu isim taşıyıcı niteliktedir: @PreTrainedConfig.register_subclass parametresine geçirdiğiniz dize, MyPolicy.name sınıf özniteliği ve make_<name>_pre_post_processors fabrika fonksiyonuyla (her biri hakkında aşağıda daha fazla bilgi) eşleşmelidir.

Yapılandırma sınıfı

PreTrainedConfig sınıfından türetin ve politika tipinizi kaydedin. İşte bir şablon — politika mimarinizin ve eğitim gereksinimlerinize göre parametreleri ve yöntemleri gerektiği gibi özelleştirin.

# configuration_my_policy.py
from dataclasses import dataclass, field
import torch
from lerobot.configs import PreTrainedConfig
from lerobot.optim import AdamWConfig
from lerobot.optim import CosineDecayWithWarmupSchedulerConfig

@PreTrainedConfig.register_subclass("my_policy")
@dataclass
class MyPolicyConfig(PreTrainedConfig):
    """Configuration class for MyPolicy.

    Args:
        n_obs_steps: Number of observation steps to use as input
        horizon: Action prediction horizon
        n_action_steps: Number of action steps to execute
        hidden_dim: Hidden dimension for the policy network
        # Add your policy-specific parameters here
    """

    dtype: torch.dtype | None = torch.bfloat16

    horizon: int = 50
    n_action_steps: int = 50
    hidden_dim: int = 256

    optimizer_lr: float = 1e-4
    optimizer_weight_decay: float = 1e-4

    def __post_init__(self):
        super().__post_init__()
        if self.n_action_steps > self.horizon:
            raise ValueError("n_action_steps cannot exceed horizon")

    def validate_features(self) -> None:
        """Validate input/output feature compatibility.

        Call this explicitly from your policy's __init__ — the base class does not.
        """
        if not self.image_features:
            raise ValueError("MyPolicy requires at least one image feature.")
        if self.action_feature is None:
            raise ValueError("MyPolicy requires 'action' in output_features.")

    def get_optimizer_preset(self) -> AdamWConfig:
        return AdamWConfig(lr=self.optimizer_lr, weight_decay=self.optimizer_weight_decay)

    def get_scheduler_preset(self):
        """Return a LRSchedulerConfig from lerobot.optim, or None."""
        return None

    @property
    def observation_delta_indices(self) -> list[int] | None:
        """Relative timestep offsets the dataset loader provides per observation.

        Return `None` for single-frame policies. For temporal policies that consume
        multiple past or future frames, return a list of offsets, e.g. `[-20, -10, 0, 10]` for
        3 past frames at stride 10 and 1 future frame at stride 10.
        """
        return None

    @property
    def action_delta_indices(self) -> list[int]:
        """Relative timestep offsets for the action chunk the dataset loader returns."""
        return list(range(self.horizon))

    @property
    def reward_delta_indices(self) -> None:
        return None

@register_subclass parametresine geçirdiğiniz dize, MyPolicy.name (bir sonraki bölüm) ile eşleşmelidir ve kullanıcıların CLI'da --policy.type olarak sağladığı değerdir. get_optimizer_preset için, gerçekten başka bir şeye ihtiyacınız olmadıkça varsayılan olarak lerobot.optim içindeki AdamW değerini kullanın. PreTrainedConfig zaten dtype: torch.dtype | None alanını bildirir; politikanıza varsayılan bir hassasiyet vermek için bu alanı bir torch.dtype değeriyle (ör. dtype: torch.dtype | None = torch.bfloat16) yeniden bildirin.

Policy sınıfı

PreTrainedPolicy sınıfından türetin ve iki sınıf özniteliğini belirleyin — her ikisi de __init_subclass__ tarafından kontrol edilir:

# modeling_my_policy.py
import torch
import torch.nn as nn
from typing import Any

from lerobot.policies import PreTrainedPolicy
from lerobot.utils.constants import ACTION
from .configuration_my_policy import MyPolicyConfig

class MyPolicy(PreTrainedPolicy):
    config_class = MyPolicyConfig  # must match the string in @register_subclass
    name = "my_policy"

    def __init__(self, config: MyPolicyConfig, dataset_stats: dict[str, Any] = None):
        super().__init__(config, dataset_stats)
        config.validate_features()  # not called automatically by the base class
        self.config = config
        self.model = ...  # your nn.Module here

    def reset(self):
        """Reset per-episode state. Called by lerobot-eval at the start of each episode."""
        ...

    def get_optim_params(self) -> dict:
        """Return parameters to pass to the optimizer (e.g. with per-group lr/wd)."""
        return {"params": self.parameters()}

    def predict_action_chunk(self, batch: dict[str, torch.Tensor], **kwargs) -> torch.Tensor:
        """Return the full action chunk (B, chunk_size, action_dim) for the current observation."""
        ...

    def select_action(self, batch: dict[str, torch.Tensor], **kwargs) -> torch.Tensor:
        """Return a single action for the current timestep (called every step at inference)."""
        ...

    def forward(self, batch: dict[str, torch.Tensor]) -> tuple[torch.Tensor, dict | None]:
        """Compute the training loss.

        Returns `(loss, output_dict)`. `output_dict` may be `None`; everything in it must be
        logging-friendly Python natives (no tensors with gradients).

        `batch["action_is_pad"]` is a bool mask of shape (B, horizon) that marks
        timesteps padded because the episode ended before `horizon` steps; you
        can exclude those from your loss.
        """
        actions = batch[ACTION]
        action_is_pad = batch.get("action_is_pad")
        ...
        return loss, {"some_loss_component": some_loss_component.item()}

Eğitim/değerlendirme döngüleri tarafından çağrılan yöntemler:

YöntemKullananlarNe işe yarar
reset() -> Nonelerobot-evalHer bölümün başında bölüm başına durumları temizleyin.
select_action(batch, **kwargs) -> Tensorlerobot-evalSonraki eylemi (B, action_dim) döndürür. Her adımda çağrılır.
predict_action_chunk(batch, **kwargs) -> Tensorkendi politikaBir eylem parçası döndürür (B, chunk_size, action_dim). Şu anda temel sınıfta soyut — politikanız parçalama yapmıyorsa NotImplementedError fırlatın.
forward(batch, reduction="mean") -> tuple[Tensor, dict \| None]lerobot-train(loss, output_dict) döndürür. Örnek başına ağırlıklandırmayı desteklemek istiyorsanız reduction="none" kabul edin.
get_optim_params() -> dictoptimizörBasit politikalar için self.parameters() döndürün; çoklu optimizatör politikaları için adlandırılmış parametre sözlüğü döndürün (grup başına öğrenme oranı örneği için modeling_act.py içindeki get_optim_params işlevine bakın).
update() -> None (isteğe bağlı)lerobot-trainHer optimizör adımından sonra tanımlıysa çağrılır. EMA, hedef ağlar, tekrar tamponları için kullanın (TDMPC bunu kullanır).

Batches, lerobot.utils.constants içindeki sabitlerle anahtarlanan düz sözlüklerdir: OBS_STATE (observation.state.<motor>), OBS_IMAGES (observation.images.<camera>), OBS_LANGUAGE, ACTION vb. Sabitleri yeniden kullanın — yeni önekler icat etmeyin.

Modeliniz parçalı çoklu GPU eğitimi gerektirecek kadar büyükse, FSDP sarma birimlerini de bildirin — parçalamanın üzerinde çalıştığı tekrarlanan blok sınıfları:

class MyPolicy(PreTrainedPolicy):
    ...
    _fsdp_wrap_modules = ["MyTransformerBlock"]

Bu tek bildirimle, --parallelism.dp_shard=N politikası için kutudan çıktığı gibi çalışır (kullanıcılar yine de --accelerator.fsdp.wrap_modules ile bunu geçersiz kılabilir). Sarım kaynağı olmadan, parçalı çalıştırmalar tasarım gereği başlangıçta başarısız olur.

İşleyici işlevleri

LeRobot, politikanızın etrafında girdileri normalize etmek ve çıktıları denormalize etmek için PolicyProcessorPipeline kullanır. Somut bir referans için processor_act.py veya processor_diffusion.py dosyalarına bakın.

Buraya dikkatle bakın: işlemciler, yeniden üretilebilirlik açısından en yaygın sorun kaynağıdır. Normalizasyon modundaki (IDENTITY ile MEAN_STD, MIN_MAX veya QUANTILES/QUANTILE10 arasında) veya hangi özelliklerin normalize edildiğine dair bir uyumsuzluk, eğitim ve değerlendirme sırasında hata vermeden çalışmasına rağmen sonuçları sessizce bozabilir. Modların, kontrol noktasının (checkpoint) eğitildiği şekildeyle eşleştiğinden, gerekli istatistiklerin mevcut olduğundan (ör. QUANTILES için q01/q99 gerekir) ve ön işlemci ile son işlemcinin tutarlı kaldığından emin olun.

# processor_my_policy.py
from typing import Any
import torch

from lerobot.processor import PolicyAction, PolicyProcessorPipeline


def make_my_policy_pre_post_processors(
    config,
    dataset_stats: dict[str, dict[str, torch.Tensor]] | None = None,
) -> tuple[
    PolicyProcessorPipeline[dict[str, Any], dict[str, Any]],
    PolicyProcessorPipeline[PolicyAction, PolicyAction],
]:
    preprocessor = ...   # build your PolicyProcessorPipeline for inputs
    postprocessor = ...  # build your PolicyProcessorPipeline for outputs
    return preprocessor, postprocessor

Önemli — fonksiyon adlandırması: LeRobot, işleyicinizi adıyla keşfeder. Zorunlu olarak fonksiyonun adı make_{policy_name}_pre_post_processors olmalıdır (@PreTrainedConfig.register_subclass parametresine geçirdiğiniz dizeyle eşleşmelidir).

İsteğe bağlı: bir kontrol noktasından yüklenen işleyicilerin ayarlanması

make_{policy_name}_pre_post_processors yalnızca işlemciler sıfırdan oluşturulduğunda çalışır. Bir kontrol noktası söz konusu olduğunda (ince ayarlama, devam etme veya değerlendirme), LeRobot bunun yerine ağırlıkların yanında serileştirilmiş boru hatlarını yükler ve çağıranın geçersiz kılma ayarlarını uygular.

Eğer politikanızın yüklendiği o hatları ayarlaması gerekiyorsa, aynı modüle, make_{policy_name}_pre_post_processors_from_pretrained adında isteğe bağlı ikinci bir fonksiyon ekleyin. LeRobot bunu aynı adlandırma kuralıyla bulur ve genel yüklemenin yerine onu çağırır. Özel bir şeye ihtiyaç duymayan politikalar bunu atlar.

from lerobot.processor import load_pretrained_policy_processors
from lerobot.utils.constants import (
    POLICY_POSTPROCESSOR_DEFAULT_NAME,
    POLICY_PREPROCESSOR_DEFAULT_NAME,
)


def make_my_policy_pre_post_processors_from_pretrained(
    config,
    pretrained_path: str,
    *,
    revision: str | None = None,
    dataset_stats: dict[str, dict[str, torch.Tensor]] | None = None,
    dataset_meta: Any | None = None,
    preprocessor_overrides: dict[str, Any] | None = None,
    postprocessor_overrides: dict[str, Any] | None = None,
    preprocessor_config_filename: str = f"{POLICY_PREPROCESSOR_DEFAULT_NAME}.json",
    postprocessor_config_filename: str = f"{POLICY_POSTPROCESSOR_DEFAULT_NAME}.json",
) -> tuple[
    PolicyProcessorPipeline[dict[str, Any], dict[str, Any]],
    PolicyProcessorPipeline[PolicyAction, PolicyAction],
]:
    preprocessor, postprocessor = load_pretrained_policy_processors(
        pretrained_path,
        revision=revision,
        preprocessor_overrides=preprocessor_overrides,
        postprocessor_overrides=postprocessor_overrides,
        preprocessor_config_filename=preprocessor_config_filename,
        postprocessor_config_filename=postprocessor_config_filename,
    )
    ...  # reconcile the loaded pipelines with the current `config`
    return preprocessor, postprocessor

Çalışan örnekler için bkz. processor_evo1.py (yeniden dolguyu normalizasyon istatistikleri), processor_groot.py (ham üst akış denetim noktalarını işler) ve processor_molmoact2.py (geçersiz kılma anahtarlarını yeniden adlandırır).

Eylemlerin yanı sıra bir tahmin döndürme (hayali kareler, alt görevler, kutular)

Bir politika, aldığı aksiyonun yanı sıra beklediği veya inandığı şeyleri de döndürebilir; örneğin bir dünya modelinin hayal ettiği kareler, tahmin edilen bir alt görev veya sınırlayıcı kutular. Bu nedenle --display_data, bunları Rerun veya Foxglove'da canlı olarak gösterir. select_action ve predict_action_chunk bir parti (batch) alır ve ya çıplak bir aksiyon tensörü (her politika için varsayılan) ya da bir PolicyOutput (lerobot.lerobot_types) döndürür: aksiyon "action" altında, PolicyPrediction ise "prediction" altında olacak şekilde, girdi partisinden farklı olarak anahtarlanmış bir parti. Tahmin, aksiyon gibi partilidir (batched), her ortam için bir değer içerir ve her giriş, referans verdiği şeyle anahtarlanır:

  • observation: gözlem anahtarına göre tahmin edilen gelecekteki gözlem ("observation.images.top" -> [B, C, H, W] kareleri). prediction.images.top olarak gösterilir.
  • language: her ortam için birer dize, etiketleme stiline göre ("subtask", "plan", "memory"), etiketleme hattının dil sütunlarının stilleri. prediction.subtask olarak görüntülenir.
  • boxes: Gözlem görüntüsü anahtarına göre çizildikleri ortam başına bir bbox cevabı, annotation VQA şemasında ({"detections": [{"label", "bbox": [x1, y1, x2, y2]}]}, görüntü oranları 0 ile 1 arası).

Çağrıcılar, policy_output_to_transition ile iki dönüş türünü normalize eder; bu fonksiyon PolicyOutput nesnesini işlemcilerin kullandığı EnvTransition türüne dönüştürür, böylece yalnızca bir şey tahmin eden politikalar değişir. Görüntüleyiciler ilk ortamı gösterir.

from lerobot.utils.constants import ACTION, PREDICTION


class MyPolicy(PreTrainedPolicy):
    def select_action(self, batch, **kwargs) -> Tensor | PolicyOutput:
        if not self._action_queue:
            chunk, extras = self.model.sample(batch)
            self._action_queue.extend(chunk.transpose(0, 1))
            if self.config.return_prediction:  # a config field of your choosing
                # The prediction goes with the step that computed it; the others return a bare action.
                prediction = {
                    "observation": {"observation.images.top": extras.next_frames},  # [B, C, H, W]
                    "language": {"subtask": extras.subtasks},  # list[str], one per env
                    "boxes": {
                        "observation.images.top": [
                            {"detections": [{"label": "cube", "bbox": xyxy}]} for xyxy in extras.cube_xyxy
                        ]
                    },
                }
                return {ACTION: self._action_queue.popleft(), PREDICTION: prediction}
        return self._action_queue.popleft()
  • Bir tahmin, bu adım için değerleri tutar. Bir parçayı kapsayanlar, örneğin hayali bir klip, parça parça döndürülür: her adım, hizmet ettiği eyleme karşılık gelen kısmı döndürür.
  • Her giriş, yeniden döndürülene kadar ekranda kalır. Bir kameranın kutularını temizlemek için boş detections döndürün.
  • Predicting, politikanızın yapılandırması üzerinden isteğe bağlı olarak etkinleştirilir ve devre dışı bırakıldığında hiçbir maliyet oluşturmaz.
  • Bir tahmin asla eylemleri değiştirmez ve yalnızca eylem postprocessor üzerinden geçer. Politikayı yönlendirmesi gereken metin, örneğin bir sonraki alt görev, generate_text (aşağıda) üzerinden geçer.

Metin yeteneğine sahip politikalar

Dil politikaları, iki işlemci adımı arasında tarif işleme (rendering) paylaşımı yapar:

  • RenderTrainingMessagesStep, veri seti dil etiketlerini işlenmiş mesajlara dönüştürür.
  • RenderRuntimeMessagesStep, kullanıcı istemlerini işlenmiş mesajlara dönüştürür.

Policy-specific işlemciler ardından sohbet biçimlendirmesini ve tokenizasyonu uygular.

Policy config, çözümlenmiş recipe: TrainingRecipe | None değerini (lerobot.datasets.recipe içinden) saklar. İsteğe bağlı recipe_path, bir YAML recipe yükleyebilir; işlemcileri oluşturmadan önce bunu çözümlen. Çözümlenmiş bir recipe, recipe tabanlı eğitimi etkinleştirir ve None, eğitim render'ını no-op yapar. Dağıtımın yerel bir YAML yoluna bağımlı olmaması için çözümlenmiş recipe'yi config ve işlemcide serialize edin. Recipe destekli render, recipe'lerin şu anda lerobot.datasets altında yer alması nedeniyle dataset ekini gerektirir.

Her iki rendereri de politika yerel sohbet biçimlendirmesi ve tokenizasyonundan önce yerleştirin:

input_steps = [
    RenderRuntimeMessagesStep(config.recipe),
    RenderTrainingMessagesStep(config.recipe),
    # observation transforms
    # policy-native roles, image placement, chat template, and tokenization
    # device placement
]

Aynı pipeline, eğitim ve çıkarım için kaydedilir ve yüklenir. Çalışma zamanı işleme yalnızca açık bir query_kind için çalışır. Eğitim işleme, çalışma zamanı sorgularını atlar ve bir tarif yapılandırılmışsa örnekleri ham etiketlerle veya eylem hedefleriyle işler. Sıradan, yalnızca gözlem içeren girdiler olduğu gibi geçer. Eylem tensörü olmadan etiketli, yalnızca metin tabanlı eğitim desteklenir. Etiket olmadan eğitim, görev yedeğini etkinleştirmek için eylem hedefleri gerektirir.

Ortak fabrika yalnızca işlemcileri oluşturur veya yükler. Dil-recipe ince ayarı, bunları etkin yapılandırma ve veri seti istatistiklerinden oluşturur; böylece kaydedilmiş bir işlemci yeni recipe'i geçersiz kılamaz. Devam etme ve çıkarım, recipe'leri ve istatistikleri de dahil olmak üzere kaydedilmiş pipeline'ları yükler. Dil dışı eğitim, mevcut oluşturma ve checkpoint yükleme davranışını korur. Yeni fabrikalar, normalizasyon ve göreli-aksiyon ayarlarını kendileri türetir. Yeni fabrikalar yapılandırılmış cihazı kullanır; mevcut veri seti parti ön işleme, eğitim yeniden adlandırma haritasını uygular.

messages_rendered, yerel sohbet biçimlendirmesi veya tokenizasyonundan önce, tarif genişletmeli anlamsal mesajları içerir. Eğitim yan dosyaları bu aynı listeyi dizinler. Mesaj yardımcıları lerobot.utils.language içinde bulunur.

Etkileşimli dağıtım query_kind ve query_text ekler. Çalışma zamanı işleme şunları destekler:

  • vqa: çağıranın sorusunu kullanıcı mesajı olarak korur.
  • next_subtask: ${subtask}'i denetleyen asistan turunu içermeyecek şekilde, kontrol noktası tarifini o tura kadar (o tur hariç) oluşturur.

Politika, ardından dekodlayıcısını mevcut politika API'si üzerinden açığa çıkarır:

class MyPolicy(PreTrainedPolicy):
    def supports_text_generation(self) -> bool:
        return True

    def generate_text(self, batch) -> str:
        token_ids = self.model.generate(**batch)
        return self.tokenizer.decode(token_ids, skip_special_tokens=True)

generate_text, model için hazır işlemci çıktısını tüketir; çağıranın prompt'unu yeniden oluşturamaz veya yeniden tokenleştiremez. Eğitim sırasında, politika yerel tokenizer, yalnızca seçilen asistan aralıklarını denetlemek için target_message_indices kullanır. Tarif, dil politikasının yapılandırmasında saklanmalıdır; böylece checkpoint ile birlikte serialize edilir ve dağıtım, eğitim için kullanılan prompt'u yeniden oluşturur.


Yol A: Ağaç dışı eklenti

Bir politikayı en hızlı şekilde yayına alma yolu: onu bağımsız bir Python dağıtımı olarak paketleyip LeRobot ile birlikte yüklemek. PR gerekmez, sürüm döngüsünün sahibi sizsiniz ve kendi ad alanınız altında PyPI'ye yayınlayabilirsiniz.

Paket yapısı

Öneki lerobot_policy_ (ÖNEMLİ!) olan ve ardından politika adınızın geldiği bir paket oluşturun:

lerobot_policy_my_policy/
├── pyproject.toml
└── src/
    └── lerobot_policy_my_policy/
        ├── __init__.py
        ├── configuration_my_policy.py
        ├── modeling_my_policy.py
        └── processor_my_policy.py

pyproject.toml

[project]
name = "lerobot_policy_my_policy"
version = "0.1.0"
dependencies = [
    # your policy-specific dependencies
]
requires-python = ">= 3.12"

[build-system]
build-backend = # your-build-backend
requires = # your-build-system

Paket __init__.py

Sınıfınızı paketin __init__.py dosyasında dışa açın ve eksik lerobot durumuna karşı koruma uygulayın:

# __init__.py
"""Custom policy package for LeRobot."""

try:
    import lerobot  # noqa: F401
except ImportError:
    raise ImportError(
        "lerobot is not installed. Please install lerobot to use this policy package."
    )

from .configuration_my_policy import MyPolicyConfig
from .modeling_my_policy import MyPolicy
from .processor_my_policy import make_my_policy_pre_post_processors

__all__ = [
    "MyPolicyConfig",
    "MyPolicy",
    "make_my_policy_pre_post_processors",
]

Yükle ve kullan

cd lerobot_policy_my_policy
pip install -e .

# Or install from PyPI if published
pip install lerobot_policy_my_policy

Kurulum tamamlandıktan sonra, politikanız LeRobot'un eğitim ve değerlendirme araçlarıyla otomatik olarak entegre edilir:

lerobot-train \
    --policy.type my_policy \
    --dataset.repo_id lerobot/pusht \
    --env.type pusht \
    --steps 200000 \
    --policy.push_to_hub false

Yol B: Ağaç içine katkıda bulunma

Politikanız istikrar kazandığında ve kütüphaneyle birlikte dağıtılmasının açık bir değeri olduğunda, doğrudan LeRobot'a ekleyebilirsiniz. Önce genel katkı kılavuzunu ve PR şablonunu okuyun — her PR'ın karşılaması gereken test/kalite beklentilerini (pre-commit run -a, pytest, topluluk incelemesi kuralı vb.) burada bulacaksınız. Aşağıdaki, bunun üzerine eklenen politika-özel katmandır.

Ağaç içi yerleşimi

src/lerobot/policies/my_policy/
├── __init__.py                    # re-exports config + modeling + processor factory
├── configuration_my_policy.py     # MyPolicyConfig + @register_subclass
├── modeling_my_policy.py          # MyPolicy(PreTrainedPolicy)
├── processor_my_policy.py         # make_my_policy_pre_post_processors
└── README.md                      # symlink → ../../../../docs/source/policy_my_policy_README.md

İki not:

  • Kaynağın yanındaki README.md, docs/source/policy_<name>_README.md içine giden bir sembolik bağlantıdır — asıl dosya docs/ altında bulunur. Mevcut politikalar (act, smolvla, diffusion, …) hepsi bunu yapar; bu sembolik bağlantılardan birini kopyalayın. Politika README'si geleneksel olarak minimaldir: makale bağlantısı + BibTeX alıntısı.
  • Kullanıcıya yönelik eğitim içeriği — nelerin kurulacağı, nasıl eğitim verileceği, hiperparametreler, benchmark değerleri — ayrı olarak docs/source/<my_policy>.mdx dosyasında bulunur ve _toctree.yml dosyasında “Policies” başlığı altında kayıtlıdır.

Dosya adları taşıyıcı niteliktedir: fabrika, isim üzerinden tembel içe aktarma yapar ve işlemci, make_<policy_name>_pre_post_processors kuralı ile keşfedilir.

Bağlantı

İki yerin politikanızdan haberdar olması gerekir. İkisi de adıyla.

  1. policies/__init__.py — MyPolicyConfig sınıfını yeniden dışa aktarın ve __all__ listesine ekleyin. Bu içe aktarma, politikanızın kaydedilmesini sağlar: @PreTrainedConfig.register_subclass("my_policy") çalışır ve o andan itibaren fabrika her şeyi sözleşmeye göre çözer. Modelleme sınıfını yeniden dışa aktarmayın; fabrika üzerinden tembel yüklenir (böylece import lerobot hızlı kalır).
  2. templates/lerobot_modelcard_template.md ve kök dizindeki README.md — bu şablon, politikanızla eğitilen her checkpoint'in model kartına eğitim sonu yayıncısı tarafından işlenen şeydir: model_name dallarına politikanızın tek satırlık bir açıklamasını ekleyin, kartların MDX rehberinize bağlanabilmesi için policy_docs içinde eşleyin ve isteğe bağlı olarak diagrams içine bir mimari görseli ekleyin. Ardından politikanızı, kök dizindeki README.md dosyasındaki modeller tablosuna, doğru kategori altında, doküman sayfanıza bağlantı vererek ekleyin.

Yapısal olarak size benzer olan mevcut bir politikayı aynalayın; fark küçük.

Ağır / isteğe bağlı bağımlılıklar

Çoğu politika, ağır bir omurga (transformer'lar, diffuser'lar, belirli bir VLM SDK'sı) gerektirir. Mevcut olduğu her yerde, mimariyi ağaç içinde yeniden uygulamak yerine onu örneğin transformers veya diffusers gibi kaynaklardan yüklemeyi tercih edin.

Sözleşme iki aşamalı kapılamadır: modülün başında TYPE_CHECKING ile korunan bir içe aktarma ve yapıcıda require_package çalışma zamanı kontrolü. modeling_diffusion.py kanonik referanstır:

from typing import TYPE_CHECKING
from lerobot.utils.import_utils import _diffusers_available, require_package

if TYPE_CHECKING or _diffusers_available:
    from diffusers.schedulers.scheduling_ddim import DDIMScheduler
else:
    DDIMScheduler = None  # keeps the symbol bindable at import time

class DiffusionPolicy(PreTrainedPolicy):
    def __init__(self, config):
        require_package("diffusers", extra="diffusion")
        super().__init__(config)
        ...

Bu şekilde:

  • import lerobot.policies, ek paket kurulmamış olsa bile çalışmaya devam eder (sembol yalnızca None değerine bağlanır).
  • Tip denetleyiciler gerçek sembolü görür.
  • Ekstra olmadan politika örneklenirse, pip install 'lerobot[diffusion]' komutuna işaret eden açık bir ImportError yükseltilir.

Eşleşen bir extra'yı pyproject.toml dosyasındaki [project.optional-dependencies] bölümüne ekleyin ve pip install 'lerobot[all]' komutunun her şeyi kurmaya devam etmesi için all extra'sına dahil edin.

Modelleme dosyasını kopyalamaktan kaçının — bunun yerine alt sınıf oluşturun

Politikanız, transformers içinde zaten var olan bir omurgayı (backbone) değiştirmeyi gerektiriyorsa (özel koşullandırma, ek girdiler, değiştirilmiş bir alt modül), o modeling_*.py dosyasının bir kopyasını projeye dahil etmeyin. Bunun yerine, en küçük upstream birimden türetme yapın (subclass) ve yalnızca değişen kısımları geçersiz kılın (override). pi_gemma.py bunun kanonik referansıdır: ~2.000 satırlık modeling dosyasını forklamak yerine, GemmaModel/PaliGemmaModel sınıflarından türetme yaparak ve decoder katmanının forward işlevini geçersiz kılma yoluyla PaliGemma/Gemma'ya AdaRMS koşullandırmasını ~370 satırda enjekte eder. Yüklenmiş yerel bir model üzerinde model cerrahisi (katman kısaltma, tokenizer genişletme, gizli durum yakalama) da uygundur (çalışan örnekler için bkz. evo1/internvl3_embedder.py, eo1/modeling_eo1.py, groot/groot_n1_7.py). Bir PR kopyalanmış bir modeling dosyasıyla geldiğinde, inceleme uzmanları bu deseni talep edecektir; kabul edilen tek istisna, transformers içinde hiç var olmayan bir modeldir.

Benchmarks ve yayımlanmış bir checkpoint

Yeni bir politika, çalışan bir kontrol noktası ve yeniden üretebileceğiniz en az bir sayı ile birlikte geldiğinde gözden geçirilmesi çok daha kolay — ve çok daha faydalı — olur.

En az bir ağaç içi (in-tree) benchmark seçin. LeRobot, benchmark başına Docker görüntüleriyle simülasyon benchmark'ları sunar (LIBERO, LIBERO-plus, Meta-World, RoboTwin 2.0, RoboCasa365, RoboCerebra, RoboMME, VLABench ve daha fazlası). Politikanızın modalitesiyle eşleşen benchmark'ı seçin — VLAs genellikle LIBERO veya VLABench'e gider; yalnızca görüntü tabanlı BC ise LIBERO veya Meta-World'e. Tam liste, doküman kenar çubuğundaki Benchmarks bölümünde yer alır.

Kontrol noktasını ve işlemcileri Hub'a lerobot/<policy>_<benchmark> altında (yazma erişiminiz yoksa kendi ad alanınızı kullanın; bir bakıcı bunu aynalayabilir) yükleyin. En kolay yöntem, --policy.repo_id=<namespace>/<repo> ve --policy.push_to_hub=true ile eğitim yapmaktır: lerobot-train, çalışmanın sonunda modeli, her iki işlemciyi ve bir model kartını yayımlar. Mevcut bir kontrol noktasını sonradan yayımlamak için, pretrained_model/ dizinini (ör. hf upload) yükleyin veya parçalı biçimdeki kontrol noktaları için lerobot-convert-dcp --push_to_hub=... kullanın.

Politikanızın MDX dosyasında sonuçları raporlayın, herkesin yeniden çalıştırabilmesi için tam lerobot-eval komutunu ve donanımı belirtin:

## Results

Evaluated on LIBERO with `lerobot/<policy>_libero`:

| Suite          | Success rate | n_episodes |
| -------------- | -----------: | ---------: |
| libero_spatial |        87.5% |         50 |
| libero_object  |        93.0% |         50 |
| libero_goal    |        81.5% |         50 |
| libero_10      |        62.0% |         50 |
| **average**    |    **81.0%** |        200 |

Reproduce: `lerobot-eval --policy.path=lerobot/<policy>_libero --env.type=libero --env.task=libero_spatial --eval.n_episodes=50` (1× A100 40 GB).

Tutarlı başarı oranı tahminleri için her suite başına n_episodes ≥ 50 kullanın.

Eğer politikanız yalnızca gerçek robotu kapsıyorsa ve hiçbir simülasyon benchmark'u uygulanmıyorsa, simülasyon değerlendirmesini şunlarla değiştirin: Hub'da herkese açık bir eğitim veri seti, lerobot-train komutu, checkpoint ve lerobot-rollout --policy.path=... ile ≥10 epizot üzerinden gerçek robot başarı oranı.

PR kontrol listesi

Genel beklentiler CONTRIBUTING.md ve PR şablonu içindedir. Bunların yanı sıra, gözden geçirmenler şunları arayacaktır:

  • MyPolicy ve MyPolicyConfig yukarıdaki kapsamı karşılar; __init_subclass__ sınıfı kabul eder.
  • policies/__init__.py yapılandırmayı yeniden dışa aktarır (bu, politikayı kaydeder; fabrika, adlandırma kuralına göre modelleme/işleyiciyi çözer).
  • make_my_policy_pre_post_processors adlandırma kuralına uyar.
  • İsteğe bağlı bağımlılıklar, [project.optional-dependencies] ekinin ve TYPE_CHECKING + require_package korumasının arkasında yer alır.
  • tests/policies/ güncellendi; geriye dönük uyumluluk artefaktı commit edildi ve politika özelinde testler eklendi.
  • src/lerobot/policies/<name>/README.md dosyası docs/source/policy_<name>_README.md içine sembolik bağlantı olarak eklenir; kullanıcıya yönelik docs/source/<name>.mdx dosyası yazılır ve _toctree.yml dosyasına eklenir.
  • lerobot-train --policy.type my_policy ... en az birkaç adım boyunca uçtan uca çalışır ve lerobot-eval veya lerobot-rollout tarafından yüklenebilir ve çalıştırılabilir bir kontrol noktası kaydeder.
  • templates/lerobot_modelcard_template.md dosyasında bir açıklama girişi ve politikanız için bir policy_docs bağlantısı bulunur.
  • Kök dizindeki README.md dosyasındaki modeller tablosu, politikanızı ilgili kategoride listeler ve doküman sayfanıza bağlantı verir.
  • Politika MDX'sinde yayınlanmış bir checkpoint ile en az bir tekrarlanabilir benchmark değerlendirmesi (sim benchmark veya gerçek robot veri seti + checkpoint).

Temiz bir PR almak için en hızlı yol, mevcut politikalar arasında size en yakın olanının dizinini kopyalamak, yeniden adlandırmak ve içeriği yöntem yöntem değiştirmektir. Her şey cilalanana kadar beklemeyin — bir taslak PR'ı erken açın ve bizimle birlikte geliştirin; gözden geçirenler, yarı bitmiş bir dal üzerinde geri bildirim vermeyi, tamamen birleştirilmiş bir dal üzerinde vermeye tercih eder.


Örnekler ve topluluk katkıları

Bu örnek politika uygulamalarına göz atın:

LeRobot'a yeni bir politika getirmek için ayırdığınız zaman için teşekkürler. main'e eklenen her mimari — ve topluluk tarafından yayınlanan her eklenti — kütüphaneyi bir sonraki kişi için biraz daha kullanışlı, robot öğrenmesinin nereye gittiğini biraz daha yansıtıcı hale getiriyor. Ne yayınlayacağınızı görmek için sabırsızlanıyoruz. 🤗

Update on GitHub