Instructions to use chomeed/robometer-4b-full-threading-d0 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use chomeed/robometer-4b-full-threading-d0 with Transformers:
# Load model directly from transformers import AutoProcessor, RFM processor = AutoProcessor.from_pretrained("chomeed/robometer-4b-full-threading-d0") model = RFM.from_pretrained("chomeed/robometer-4b-full-threading-d0", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Model card: full FT vs LoRA results, autocast caveat, repro command
Browse files
README.md
CHANGED
|
@@ -4,17 +4,100 @@ base_model: Qwen/Qwen3-VL-4B-Instruct
|
|
| 4 |
tags:
|
| 5 |
- reward_model
|
| 6 |
- rbm
|
| 7 |
-
-
|
|
|
|
| 8 |
library_name: transformers
|
| 9 |
---
|
| 10 |
|
| 11 |
-
#
|
| 12 |
|
| 13 |
-
|
|
|
|
|
|
|
| 14 |
|
| 15 |
-
|
| 16 |
-
-
|
|
|
|
| 17 |
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
tags:
|
| 5 |
- reward_model
|
| 6 |
- rbm
|
| 7 |
+
- robometer
|
| 8 |
+
- mimicgen
|
| 9 |
library_name: transformers
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Robometer-4B Full Fine-tune — MimicGen threading_d0
|
| 13 |
|
| 14 |
+
Full-parameter fine-tune of [`robometer/Robometer-4B`](https://huggingface.co/robometer/Robometer-4B)
|
| 15 |
+
(Qwen3-VL-4B-Instruct) on MimicGen `threading_d0` rollouts. Emits, per frame, a
|
| 16 |
+
**progress** value in [0,1] and a **success probability**.
|
| 17 |
|
| 18 |
+
This is the no-PEFT counterpart of
|
| 19 |
+
[`chomeed/robometer-4b-lora-threading-d0`](https://huggingface.co/chomeed/robometer-4b-lora-threading-d0):
|
| 20 |
+
identical data, schedule, and eval config — the only change is `model.use_peft=false`.
|
| 21 |
|
| 22 |
+
- **4.03B trainable params (90.7%)** — language model + all three prediction heads; the vision
|
| 23 |
+
tower stays frozen (`train_vision_encoder: false`), same as the LoRA run
|
| 24 |
+
- 1000 steps, batch 8, lr 2e-5, cosine, warmup 0.1, weight decay 0.01, grad-norm clip 10
|
| 25 |
+
- bf16 full fine-tuning via Unsloth; **34 GB peak** on one B200 (the LoRA run peaked at 14.7 GB)
|
| 26 |
+
- Uploaded checkpoint is **step 500**, the best of the run by mean(pearson, kendall_last)
|
| 27 |
+
- Data: [`chomeed/mimicgen_threading_d0_train_rfm`](https://huggingface.co/datasets/chomeed/mimicgen_threading_d0_train_rfm)
|
| 28 |
+
(160 traj: 80 successful + 80 failure), evaluated on
|
| 29 |
+
[`..._test_rfm`](https://huggingface.co/datasets/chomeed/mimicgen_threading_d0_test_rfm) (40 traj, disjoint seeds)
|
| 30 |
|
| 31 |
+
## Results (held-out, 40 trajectories with unseen seeds)
|
| 32 |
+
|
| 33 |
+
Best checkpoint of each run, scored by the trainer's own eval:
|
| 34 |
+
|
| 35 |
+
| metric | full FT (step 500) | LoRA (step 600) |
|
| 36 |
+
|---|---|---|
|
| 37 |
+
| reward-alignment Pearson | **0.9804** | 0.9753 |
|
| 38 |
+
| policy-ranking Kendall (last) | **1.000** | **1.000** |
|
| 39 |
+
| ranking acc, failure vs successful | **1.000** | **1.000** |
|
| 40 |
+
| reward-alignment eval loss | **3.236** | 3.390 |
|
| 41 |
+
| success AUPRC | 0.162 | 0.192 |
|
| 42 |
+
|
| 43 |
+
Matched-step comparison at step 1000, so the two runs are compared at equal training budget:
|
| 44 |
+
|
| 45 |
+
| metric @ step 1000 | full FT | LoRA |
|
| 46 |
+
|---|---|---|
|
| 47 |
+
| Pearson | **0.9758** | 0.9749 |
|
| 48 |
+
| success-head AUROC (threshold-free) | **0.9944** | 0.9907 |
|
| 49 |
+
| eval loss | **3.208** | 3.329 |
|
| 50 |
+
|
| 51 |
+
Full fine-tuning wins consistently but by a small margin — Pearson is higher at every matched
|
| 52 |
+
eval step, and eval loss is lower throughout. Kendall is saturated at 1.000 for both, so this
|
| 53 |
+
test set does not separate them on trajectory ranking.
|
| 54 |
+
|
| 55 |
+
**Success-head calibration:** both models emit very low absolute success probabilities
|
| 56 |
+
(peak ≈0.002 on successful held-out trajectories). Ranking is excellent (AUROC 0.99) but the
|
| 57 |
+
probabilities are not calibrated — threshold well below 0.01, or just use the progress signal.
|
| 58 |
+
|
| 59 |
+
## Usage
|
| 60 |
+
|
| 61 |
+
> **Important:** this is a full-weights checkpoint, like the upstream `robometer/Robometer-4B`.
|
| 62 |
+
> It keeps fp32 `pixel_values` against bf16 vision blocks, which is fine under the Trainer's
|
| 63 |
+
> autocast but raises `RuntimeError: expected scalar type BFloat16 but found Float` at plain
|
| 64 |
+
> inference. **Wrap the forward pass in `torch.autocast`.** (LoRA checkpoints work either way.)
|
| 65 |
+
|
| 66 |
+
```python
|
| 67 |
+
import numpy as np, torch
|
| 68 |
+
from robometer.data.dataset_types import ProgressSample, Trajectory
|
| 69 |
+
from robometer.evals.eval_server import compute_batch_outputs
|
| 70 |
+
from robometer.utils.save import load_model_from_hf
|
| 71 |
+
from robometer.utils.setup_utils import setup_batch_collator
|
| 72 |
+
|
| 73 |
+
device = torch.device("cuda")
|
| 74 |
+
exp_config, tokenizer, processor, model = load_model_from_hf(model_path="chomeed/robometer-4b-full-threading-d0", device=device)
|
| 75 |
+
model.eval()
|
| 76 |
+
collator = setup_batch_collator(processor, tokenizer, exp_config, is_eval=True)
|
| 77 |
+
|
| 78 |
+
frames = ... # uint8 (T, H, W, C), RGB, third-person view
|
| 79 |
+
traj = Trajectory(frames=frames, frames_shape=tuple(frames.shape), task="Pick up the needle and thread it through the hole in the tripod.",
|
| 80 |
+
id="0", metadata={"subsequence_length": int(frames.shape[0])}, video_embeddings=None)
|
| 81 |
+
batch = collator([ProgressSample(trajectory=traj, sample_type="progress")])
|
| 82 |
+
inputs = {k: (v.to(device) if hasattr(v, "to") else v) for k, v in batch["progress_inputs"].items()}
|
| 83 |
+
|
| 84 |
+
with torch.no_grad(), torch.autocast("cuda", dtype=torch.bfloat16): # <-- required
|
| 85 |
+
out = compute_batch_outputs(model, tokenizer, inputs, sample_type="progress",
|
| 86 |
+
is_discrete_mode=True, num_bins=10) # progress head is discrete, 10 bins
|
| 87 |
+
|
| 88 |
+
progress = np.array(out["progress_pred"][0]) # (T,) in [0,1]
|
| 89 |
+
success = np.array(out["outputs_success"]["success_probs"][0]) # (T,) in [0,1]
|
| 90 |
+
```
|
| 91 |
+
|
| 92 |
+
Serving: `python robometer/evals/eval_server.py model_path=chomeed/robometer-4b-full-threading-d0`
|
| 93 |
+
|
| 94 |
+
## Reproducing
|
| 95 |
+
|
| 96 |
+
```bash
|
| 97 |
+
TASK=mimicgen_threading_d0 GPU=0 STEPS=1000 bash run_full_task.sh
|
| 98 |
+
```
|
| 99 |
+
|
| 100 |
+
Requires `robometer/data/dataset_success_cutoff.txt` to contain
|
| 101 |
+
`mimicgen_threading_d0_train_rfm,1.0` and `mimicgen_threading_d0_test_rfm,1.0` (simulation
|
| 102 |
+
trajectories have exact endpoints), and the RFM datasets preprocessed via
|
| 103 |
+
`robometer/configs/preprocess_threading_d0.yaml`.
|