Instructions to use albus2024/dita_long with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LeRobot
How to use albus2024/dita_long with LeRobot:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
|
Download TRAINING.md from albus2024/dita_long: direct link, hf CLI and curl.
- Browser
- Download file 14 kB
-
https://huggingface.co/albus2024/dita_long/resolve/main/TRAINING.md
- Command line
-
hf download hf://albus2024/dita_long/TRAINING.md
-
curl -L -o TRAINING.md https://huggingface.co/albus2024/dita_long/resolve/main/TRAINING.md
14 kB
| # Dita full fine-tuning and LoRA | |
| The training preset follows the upstream **LIBERO-Spatial** recipe at | |
| [RoboDita/Dita `db6907d`](https://github.com/RoboDita/Dita/tree/db6907d8c0b9878570570e10d3a0599420072044). | |
| LIBERO-10 uses a higher peak LR (`5e-4`). The upstream real-robot LoRA script | |
| uses a different scheduler; the LoRA branch here uses the LIBERO preset below. | |
| This aligns the requested optimizer settings, not the complete upstream data | |
| pipeline or benchmark results. | |
| The five Hub models' runtime 2.2.0 configurations include the training fields | |
| and the saved image preprocessing device. | |
| LIBERO-Long saves peak LR `5e-4`; the other models save `1e-4`. Install the | |
| matching wheel from the model repository before loading these configurations. | |
| ## Image preprocessing | |
| `policy.image_preprocessing_device` selects the FP32 image resize and ImageNet | |
| normalization path for both training and inference: | |
| | Value | Execution device | | |
| | --- | --- | | |
| | `cpu` (default and published model setting) | CPU, preserving the reference preprocessing results | | |
| | `policy` | The model's actual device, including the local CUDA device in distributed training | | |
| Pixel validation has no configuration switch: the policy performs one `aminmax` | |
| reduction on its model device and rejects non-finite or out-of-range pixels. | |
| Shape/channel checks use tensor metadata. Preprocessing remains FP32 under AMP. | |
| To fine-tune the DROID initialization using CUDA preprocessing, add: | |
| ```bash | |
| --policy.image_preprocessing_device=policy | |
| ``` | |
| The CLI overrides the initialization's saved `cpu` value. The new checkpoint | |
| saves `policy`; loading it for inference restores the same path automatically. | |
| Both full policies and LoRA checkpoints save this field through the Dita config. | |
| Keep that saved value when resuming or deploying. CUDA interpolation may differ | |
| slightly from the CPU reference, so changing this setting on an already trained | |
| model requires checking loss, gradients, and inference actions. The published | |
| models use `cpu`; this runtime update does not assert GPU-preprocessed rollout | |
| equivalence. | |
| ## Implementation | |
| 1. `freeze_backbone=false` enables full fine-tuning of DINOv2, QFormer/FiLM, | |
| and the policy Transformer/action head. CLIP remains a frozen processor. | |
| Existing checkpoints retain an explicitly saved freeze setting. | |
| 2. `gradient_checkpointing=true` independently enables activation checkpointing | |
| in the ViT and QFormer. Both require `training` and enabled autograd before | |
| entering a checkpoint wrapper. Evaluation and `no_grad`/`inference_mode` | |
| skip the wrappers. Training uses `use_reentrant=False`, allowing gradients | |
| to reach LoRA adapters even when the base weights and input tensors are frozen. | |
| 3. LeRobot's native `--peft.*` branch wraps all Dita `nn.Linear` modules with | |
| LoRA, matching the upstream target selection. This includes the visual | |
| backbone, QFormer/FiLM, Transformer and action head. Only adapter weights | |
| are trained; `freeze_backbone=true` does not exclude backbone adapters. | |
| 4. The optimizer includes only trainable parameters, in the upstream group | |
| order: policy no-decay, policy decay, backbone no-decay, backbone decay. | |
| LoRA weights use the same grouping rules after adapter injection. | |
| 5. The registered `dita` scheduler is serialized by LeRobot so optimizer and | |
| scheduler state can be restored on resume. | |
| | Setting | Source default | | |
| | --- | --- | | |
| | `freeze_backbone` | `false` | | |
| | `gradient_checkpointing` | `true` | | |
| | `optimizer_lr` | `0.0001` | | |
| | `optimizer_backbone_lr_scale` | `0.1` | | |
| | `optimizer_betas` | `[0.9, 0.95]` | | |
| | `optimizer_eps` | `1e-8` | | |
| | `optimizer_weight_decay` | `0.05` | | |
| | Bias and parameters with at most one dimension | Weight decay `0` | | |
| | `optimizer_grad_clip_norm` | `0` (disabled by LeRobot) | | |
| | `scheduler_warmup_steps` | `1000` | | |
| | `scheduler_decay_steps` | `100000` | | |
| | `scheduler_min_lr_scale` | `0.01` | | |
| | `lora_dropout` | `0.0` | | |
| The schedule starts at zero LR, linearly warms up to the peak at step 1000, | |
| then follows the upstream cosine expression to 1% of the peak at step 100000. | |
| The backbone/policy LR ratio stays at 0.1 throughout. Short `--steps` runs do | |
| not compress this schedule. The upstream expression continues the cosine | |
| beyond the configured period; finish at `scheduler_decay_steps` or explicitly | |
| choose a longer period for longer runs. | |
| Sources: [parameter groups and scheduler](https://github.com/RoboDita/Dita/blob/db6907d8c0b9878570570e10d3a0599420072044/scripts/train_diffusion_oxe.py#L69), | |
| [LIBERO commands](https://github.com/RoboDita/Dita/blob/db6907d8c0b9878570570e10d3a0599420072044/README.md#L98), | |
| [LoRA targets and initialization](https://github.com/RoboDita/Dita/blob/db6907d8c0b9878570570e10d3a0599420072044/scripts/finetune_realdata.py#L242). | |
| ## Full fine-tuning | |
| Install the current source: | |
| ```bash | |
| pip install -e ".[training]" | |
| ``` | |
| Use explicit overrides when starting from an older converted checkpoint. Its | |
| saved `optimizer_lr`, weight decay, clipping and freeze fields take precedence | |
| over new dataclass defaults. This starts a new training run; resuming an old | |
| run preserves that run's saved optimizer/scheduler state instead. | |
| ```bash | |
| lerobot-train \ | |
| --policy.path=albus2024/dita_droid_pretrain \ | |
| --policy.device=cuda \ | |
| --policy.dtype=bfloat16 \ | |
| --policy.input_features=null \ | |
| --policy.gripper_mode=binary \ | |
| --policy.freeze_backbone=false \ | |
| --policy.gradient_checkpointing=true \ | |
| --policy.optimizer_lr=0.0001 \ | |
| --policy.optimizer_backbone_lr_scale=0.1 \ | |
| --policy.optimizer_weight_decay=0.05 \ | |
| --policy.optimizer_grad_clip_norm=0 \ | |
| --policy.scheduler_warmup_steps=1000 \ | |
| --policy.scheduler_decay_steps=100000 \ | |
| --policy.scheduler_min_lr_scale=0.01 \ | |
| --policy.push_to_hub=false \ | |
| --dataset.repo_id=YOUR_USERNAME/YOUR_LIBERO_SPATIAL_DATASET \ | |
| --output_dir=outputs/train/dita_full \ | |
| --batch_size=64 --steps=100000 | |
| ``` | |
| The upstream LIBERO example uses eight GPUs, each with batch size 64. The | |
| command above is a single-process example; matching effective batch size is a | |
| separate training choice. Set `--policy.optimizer_lr=0.0005` for the upstream | |
| LIBERO-10 LR. For continuous position grippers use | |
| `--policy.gripper_mode=continuous` and the appropriate target dataset. | |
| ## LoRA fine-tuning | |
| ```bash | |
| pip install -e ".[lora]" | |
| ``` | |
| Add the following to the full fine-tuning command and choose a fresh output | |
| directory, for example `outputs/train/dita_lora`: | |
| ```bash | |
| --peft.method_type=LORA \ | |
| --peft.r=32 | |
| ``` | |
| The default alpha is automatically `2 * r` (64 for rank 32), initialization | |
| is Gaussian for A and zero for B, and dropout is zero. Override with | |
| `--peft.lora_alpha`, `--peft.init_type`, `--peft.target_modules` or | |
| `--policy.lora_dropout`. LeRobot's native CLI rank default is 16, so specify | |
| `--peft.r=32` explicitly for the example above. Do not set `policy.use_peft=true` | |
| when starting from a base checkpoint: that flag identifies an already saved | |
| adapter and is set by LeRobot when it wraps the policy. | |
| Adapter checkpoints contain `adapter_model.safetensors`, `adapter_config.json`, | |
| the Dita `config.json`, processors, and training state. The adapter config | |
| records the base model location; that base model must remain available. | |
| Adapters do not contain a standalone copy of the full Dita weights. | |
| ## Resume and inference | |
| Resume either training branch from its saved training configuration: | |
| ```bash | |
| lerobot-train \ | |
| --resume=true \ | |
| --config_path=outputs/train/dita_lora/checkpoints/last/pretrained_model/train_config.json | |
| ``` | |
| LeRobot's native policy factory loads full policies and saved adapters. For | |
| LIBERO evaluation, use the saved `pretrained_model` directory as | |
| `--policy.path` in the normal `lerobot-eval` command; the saved `use_peft` field | |
| selects adapter loading automatically. The same applies to LeRobot's recording | |
| and deployment entry points that use `make_policy`. | |
| For Python, use `make_policy` to load adapters, followed by the saved processors: | |
| ```python | |
| from pathlib import Path | |
| import torch | |
| from lerobot.configs.policies import PreTrainedConfig | |
| from lerobot.policies.factory import make_policy, make_pre_post_processors | |
| import lerobot_policy_dita # Register the Dita config, scheduler and processors. | |
| path = Path("outputs/train/dita_lora/checkpoints/last/pretrained_model") | |
| config = PreTrainedConfig.from_pretrained(path) | |
| config.pretrained_path = path | |
| config.device = "cuda" | |
| policy = make_policy(config, ds_meta=dataset.meta).eval() | |
| pre, post = make_pre_post_processors(config, pretrained_path=path) | |
| with torch.inference_mode(): | |
| action = post(policy.select_action(pre(observation_batch))) | |
| ``` | |
| Here `dataset.meta` is the target LeRobot dataset metadata and | |
| `observation_batch` contains the image(s) and task text. Dita's direct | |
| `DitaPolicy.from_pretrained` loads full weights; use the factory above for | |
| adapter checkpoints. In both branches the inference entry point automatically | |
| skips activation checkpoint wrappers, even if checkpointing was enabled during | |
| training and the saved backbone freeze setting is false. | |
| ## Validation | |
| ```bash | |
| OMP_NUM_THREADS=1 pytest -q tests/test_dita_training.py | |
| pytest -q | |
| ``` | |
| The training tests use the actual Dita modules at reduced width/depth. They | |
| check full/frozen training with checkpointing on/off, gradient parity against | |
| direct forward execution, inference without checkpoint calls, optimizer groups, | |
| schedule/resume behavior, and LoRA updates plus adapter reload through LeRobot. | |
| For a short full-size check, use the real three-episode LIBERO subset described | |
| in [the training smoke test](../../scripts/README.md#native-lerobot-train-smoke-test), | |
| apply the optimizer overrides above, and run each branch with | |
| `--steps=5 --batch_size=2 --num_workers=0 --save_freq=5 --env_eval_freq=0`. | |
| Resume to step 6, then load the saved policy/adapter and run inference. Keeping | |
| the original warmup means the first optimizer call has zero LR; later calls | |
| must update the intended weights. | |
| ### Results on 2026-09-14 | |
| Environment: LeRobot 0.6.1, PyTorch 2.9.1+cu128, PEFT 0.19.1, Transformers | |
| 5.5.4, timm 1.0.24; RTX 4090 D. The repository suite passed all **321 tests**. | |
| Native training used the DROID initialization, the same three real LIBERO | |
| episodes (843 frames), BF16, batch size 2 and the unmodified 1000-step warmup. | |
| | Check | Full fine-tuning | LoRA, rank 32 | | |
| | --- | --- | --- | | |
| | Trainable parameters | 213,225,984 | 13,000,928 | | |
| | Native train/save/resume | 5 steps + resumed step 6 | 5 steps + resumed step 6 | | |
| | Intended updates | ViT, QFormer, Transformer | Adapters in all three components | | |
| | Base parameter tensors changed | 372 | 0 | | |
| | Optimizer state | Finite; step 6 | Finite; step 6 | | |
| | Restored policy/backbone LR | `6e-7` / `6e-8` | `6e-7` / `6e-8` | | |
| | Saved model inference | BF16, FP32, FP16; finite `[1, 7]` actions | Same | | |
| | Checkpoint calls in inference | 0 | 0 | | |
| | Checkpoint flags enabled vs disabled, same RNG | Exactly equal actions | Exactly equal actions | | |
| The local validation artifacts are in | |
| `workspace/validation/dita-training-20260914/`: native training logs, both | |
| checkpoints, `verify.py`, `pytest.log`, and `validation_report.json`. | |
| They are ignored by Git. These short checks do not establish convergence or | |
| robot task success. | |
| ### Runtime 2.1.0 release validation | |
| The bundled wheel separately passed all 321 tests and strict loading of all five | |
| Hub models. BF16 inference on the checked observation matched runtime 2.0.1 | |
| exactly, with zero activation-checkpoint calls. LIBERO processors restored finite | |
| actions; the DROID initialization retained its unbound processor templates. | |
| Using the candidate DROID configuration without optimizer overrides, native BF16 | |
| full fine-tuning and rank-32 LoRA each completed three steps and resumed for a | |
| fourth on the same three real LIBERO episodes. Both restored the scheduler and | |
| finite optimizer state, with policy/backbone LR `4e-7` / `4e-8` at step 4. The | |
| intended parameters updated in the ViT, QFormer and Transformer in both branches. | |
| Artifacts, hash-locked publication manifests, upload revisions and downloaded | |
| Hub verification are under `workspace/validation/dita-runtime-2.1.0/`. Each model | |
| repository also contains `runtime_validation_report.json` and archives the | |
| previous configuration and runtime metadata under `history/runtime-2.0.1/`. | |
| ### Runtime 2.2.0 image preprocessing validation | |
| All five full-size checkpoints were checked on real observations, with batch size | |
| 2, FP32/BF16/FP16, fixed RNG, and deterministic kernels. LIBERO checks used two | |
| samples from the cached three-episode subset; DROID used two SO101 samples with a | |
| 100-action horizon. Comparing the new `cpu` mode against the previous CPU image | |
| path produced exactly equal loss, all 372 parameter gradients, and inference | |
| actions in every case. CPU and `policy` modes both produced finite results. | |
| Switching existing weights to `policy` changes interpolation numerics. Across | |
| the five checkpoints, the largest measured differences were: | |
| | Compute dtype | Loss absolute difference | Gradient relative L2 difference | Normalized action absolute difference | | |
| | --- | --- | --- | --- | | |
| | FP32 | 2.87e-6 | 9.35e-5 | 6.62e-6 | | |
| | BF16 | 1.98e-3 | 1.59e-2 | 1.70e-2 | | |
| | FP16 | 3.65e-4 | 5.43e-3 | 8.22e-4 | | |
| These are maxima over a small paired numerical check, not accuracy bounds or a | |
| LIBERO success-rate evaluation. No binary gripper decisions changed in those | |
| samples. The published configs retain `cpu`; new fine-tuning can explicitly | |
| select `policy` and carry that choice into deployment. A DROID initialization | |
| overridden from `cpu` to `policy` completed two real-data updates, saved the | |
| override, and reproduced its inference actions exactly after reloading. | |
| Validation artifacts are under `workspace/validation/dita-preprocessing-20260916/`. | |
| The numerical comparison uses deterministic kernels to distinguish preprocessing | |
| effects from mixed-precision backward-kernel nondeterminism. Standard training | |
| does not need to enable deterministic algorithms to use this configuration. | |