Instructions to use ZibinDong/ActionCodec2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ZibinDong/ActionCodec2 with Transformers:
# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("ZibinDong/ActionCodec2", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 3,630 Bytes
1bfc3f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | """Explicit tokenizer pretraining and cleaning shared by both token layers."""
from __future__ import annotations
from pathlib import Path
from typing import Any
import numpy as np
from .fitting import ProfileFitter
class TrainingMixin:
def preprocess(
self,
values: np.ndarray,
*,
profile: str | None = None,
gripper_column: int | None = None,
**kwargs: Any,
) -> np.ndarray:
"""Clean a canonical ``(T,D_active)`` profile trajectory for explicit tokenizer pretraining."""
if profile is None:
profiles = {component.space for component in self.action_space.components}
if len(profiles) != 1:
raise ValueError("profile is required for layouts combining joint and EEF")
profile = profiles.pop()
if profile not in self.preprocessing:
raise ValueError(f"no recorded preprocessing for profile {profile!r}")
values = np.asarray(values)
if "ease_limits" not in kwargs and values.ndim == 2:
kwargs["ease_limits"] = self._joint_ease_limits(
profile, values.shape[1], gripper_column, kwargs.get("active_dims")
)
return self.preprocessing[profile].apply(values, gripper_column=gripper_column, **kwargs)
def _joint_ease_limits(self, profile, width, gripper_column, active_dims):
processor = self.action_tokenizer.profiles[profile].processor
component = processor.config.physical.components.get("generalized_joint_position")
if profile != "joint" or component is None or component.primitive_order != 1:
return None
domain = component.constraints["order_1"]
limits = np.full(processor.action_dim, np.inf)
limits[list(component.dims)] = np.minimum(np.abs(domain.minimum), np.abs(domain.maximum))
dims = tuple(range(width)) if active_dims is None else tuple(active_dims)
limits = limits[list(dims)]
if gripper_column is not None:
limits[gripper_column] = np.inf
return limits
def fit(
self,
episodes,
*,
fps: float | None = None,
current_state=None,
previous_first_order=None,
bootstrap_context: bool = False,
apply_preprocessing: bool = False,
preprocessing=None,
backend: str = "auto",
threads: int = 0,
batch_size: int = 256,
progress: bool = False,
max_cell_bytes: int | None = None,
work_dir: str | Path | None = None,
) -> TrainingMixin:
"""Fit vocabularies from episodes in declared source layouts."""
fitter = ProfileFitter(self, bootstrap_context=bootstrap_context,
apply_preprocessing=apply_preprocessing, preprocessing=preprocessing)
router, report = fitter.fit(
episodes,
work_dir=work_dir,
metadata=dict(
fps=fps, current_state=current_state, previous_first_order=previous_first_order
),
backend=backend,
threads=threads,
batch_size=batch_size,
progress=progress,
max_cell_bytes=max_cell_bytes,
)
replacement = type(self)(router, action_space=self.action_space.name)
replacement._fitted_profiles = self.fitted_profiles | report["profiles"].keys()
replacement.training_report = report
replacement.preprocessing = dict(fitter.preprocessing)
replacement._warned_default_fps = self._warned_default_fps
self.__dict__.update(replacement.__dict__)
return self
|