
How a continuous joint trajectory becomes tokens a transformer can predict. 256-bin discretization, the FAST DCT plus BPE scheme, real defaults, and what each choice costs.
A servo takes a number. A transformer emits a symbol from a fixed vocabulary. Action tokenization is the glue between those two facts. Get it wrong and the model trains to a low loss, the checkpoint loads, and the arm still drifts, because its symbols cannot reconstruct the motion you recorded.
Two schemes matter: per-dimension per-timestep binning, used by RT-1, RT-2 and OpenVLA, and FAST, the frequency-space scheme behind Pi0-FAST. It ends on the part most write-ups skip: none of the five policies you can fine-tune here has a tokenizer knob, and that is the right default.
What you need to know
- •Binning maps every joint value at every timestep to one of N bins, almost always 256. Token count grows with control frequency and joint count.
- •At high control rates neighbouring timesteps land in the same bin, so next-token prediction collapses onto copying: the FAST paper reports error climbing until the model repeats the first action.
- •FAST (Frequency-space Action Sequence Tokenization, arXiv 2501.09747) runs a discrete cosine transform over time, rounds the coefficients, then compresses them with byte pair encoding.
- •Measured: a 50 Hz T-shirt folding chunk drops from 700 tokens to 53, a 5 Hz BridgeV2 chunk only from 35 to 20.
- •Compression buys training speed, not inference speed: about 750 ms per chunk against about 100 ms for diffusion Pi0 on a 4090.
- •The released FAST+ tokenizer ships vocab_size 2048, not the paper's 1024. Read the config, not the PDF.
- •None of the five trainable policies here predicts tokens at inference. All output continuous actions.
The gap tokenization has to close
An episode from an SO-100 is a table of floats: six joints, one row per control tick, stored by the LeRobot dataset format. Record at 30 Hz, ask the policy for one second of motion, and one training example is a 30 by 6 block.
import numpy as np
# one second of SO-100 motion at 30 Hz, six joints, radians
chunk = np.load("episode_004_actions.npy")
print(chunk.shape, chunk.dtype) # (30, 6) float32
print(chunk.min(), chunk.max()) # -2.61 1.94
# a transformer cannot emit a float32. It emits an index into a vocabulary.
# tokenization decides how those 180 numbers become a sequence of indices.A diffusion or flow matching head sidesteps this: it regresses the block and never needs a vocabulary. An autoregressive model cannot. Its output layer is a softmax over a fixed vocabulary, so reusing its language pre-training means expressing motion in the same currency as words. What follows is driven by what a language model finds easy to predict.
Binning: one symbol per joint per tick
Take each dimension independently, split its range into N uniform bins, emit the bin index. RT-1 (arXiv 2212.06817, December 2022) set the convention everyone copied: 256 bins per dimension, uniform within each variable's bounds, over 7 arm dimensions, 3 base dimensions and one mode dimension switching between arm, base and termination.
import numpy as np
N_BINS = 256
def bin_encode(chunk, lo, hi, n_bins=N_BINS):
"""chunk: (H, D) float. Returns (H*D,) int token ids."""
clipped = np.clip(chunk, lo, hi)
idx = ((clipped - lo) / (hi - lo) * (n_bins - 1)).round().astype(int)
return idx.reshape(-1) # row-major: t0d0 t0d1 ... t0d5 t1d0 ...
def bin_decode(tokens, lo, hi, H, D, n_bins=N_BINS):
idx = np.asarray(tokens).reshape(H, D)
return lo + idx / (n_bins - 1) * (hi - lo)
# quantile bounds, not min/max: outliers otherwise eat the resolution
lo = np.quantile(all_actions, 0.01, axis=0)
hi = np.quantile(all_actions, 0.99, axis=0)
tokens = bin_encode(chunk, lo, hi)
print(len(tokens)) # 180 for a 30 x 6 chunk. One token per number.Every model made one variation. They look cosmetic and are not: the bin bounds decide how much of the 256-way resolution you actually use.
| Model | Bins | Bin bounds | How tokens enter the vocabulary |
|---|---|---|---|
| RT-1 (2022) | 256 | Uniform within each variable's bounds | Dedicated discrete output, no language vocabulary |
| RT-2, PaLI-X (2023) | 256 | Uniform | PaLI-X has unique tokens for integers up to 1000, so bins map to them directly |
| RT-2, PaLM-E (2023) | 256 | Uniform | The 256 least frequently used tokens are overwritten |
| OpenVLA (2024) | 256 | 1st and 99th quantile of training actions | The 256 least used Llama tokens, which are the last 256 |
| FAST (2025) | n/a, BPE over DCT coefficients | Quantile normalization to [-1, 1] | In lerobot, the PaliGemma tail, skipping the last 128 tokens |
OpenVLA gives the reason directly: the 1st and 99th quantile instead of min/max bounds "allows us to ignore outlier actions in the data that could otherwise drastically expand the discretization interval and reduce the effective granularity". One frame where a servo reads 4 radians because the bus dropped a packet costs resolution on every other frame. FAST inherits the advice: lerobot defaults to --normalization_mode QUANTILES. If an arm moves in visible steps, coarse bins are one candidate, alongside arm twitches then sags.
Where binning breaks, and it is not where you expect
Binning does not fail because 256 bins are too coarse. It fails on token count. One token per dimension per timestep means sequence length is H times D, so doubling the control frequency doubles the tokens per second.
| Dataset | Control frequency | Tokens per 1 s chunk, binning | Tokens per 1 s chunk, FAST | Compression |
|---|---|---|---|---|
| BridgeV2 | 5 Hz | 35 | 20 | 1.75x |
| DROID | 15 Hz | 105 | 29 | 3.6x |
| Table bussing | 20 Hz | 140 | 28 | 5.0x |
| T-shirt folding | 50 Hz | 700 | 53 | 13.2x |
Read that as a statement about your own recording rate. At 5 Hz compression is nearly irrelevant. At 50 Hz it is the difference between a workable sequence and one that dominates the context window, and every token still has to be predicted at inference.
The subtler failure is statistical. At 50 Hz the joint angle at tick t and tick t+1 usually differ by less than one bin width, so the best strategy under a next-token objective is to copy the previous token. The FAST paper measures it: as sampling density rises, error climbs until the model simply copies the first action. That model is not undertrained. It found the optimum of a badly posed objective.
A policy that has collapsed onto copying reports excellent token accuracy, because most tokens genuinely are repeats. The loss curve looks like a success. You find out when the arm holds its start pose and drifts. See loss falls, policy does nothing. Token accuracy is not a proxy for trajectory quality, and no number of extra training steps repairs it.
FAST: compress the trajectory, then tokenize the compression
The paper is by Pertsch, Stachowicz, Ichter, Driess, Nair, Vuong, Mees, Finn and Levine, submitted 16 January 2025. The idea comes from JPEG and MP3: a smooth signal is sparse in the frequency domain, so transform first and quantize second. A joint trajectory is about as smooth as signals get.
- 1Normalize the chunk
Bring every dimension into roughly [-1, 1]. Quantile normalization survives outliers. Not optional, and the step people skip.
pythonlo = np.quantile(all_actions, 0.01, axis=0) hi = np.quantile(all_actions, 0.99, axis=0) norm = 2 * (chunk - lo) / (hi - lo) - 1 norm = np.clip(norm, -1, 1) # (30, 6) - 2Discrete cosine transform along time
One orthonormal DCT per dimension over the time axis. Same shape out, but the energy moves into the low-frequency coefficients: a slow reach puts almost all of it in the first three.
pythonfrom scipy.fft import dct # tokenizer input is [batch, timesteps, action_dim], DCT over axis=1 coeff = dct(norm[None], axis=1, norm="ortho") # (1, 30, 6) - 3Scale and round
Multiply by the scale hyperparameter, round to integers. The lossy part: larger scale keeps more small coefficients and lengthens the sequence, smaller scale blurs the chunk.
pythonSCALE = 10 coeff_q = np.around(coeff * SCALE) print((coeff_q == 0).mean()) # a large fraction of coefficients are now exactly zero - 4Flatten low frequency first
Row-major flattening puts the lowest-frequency component of every dimension first, so runs of zeros end up adjacent at the tail.
pythonflat = coeff_q[0].flatten().astype(int) # length 180 # order: freq0-dim0..dim5, freq1-dim0..dim5, ... - 5Byte pair encoding over the integers
Integers become characters and BPE is trained over those strings, merging frequent runs. The runs are mostly zeros, so the tail collapses. Lossless.
python# what the shipped tokenizer literally does. min_token shifts the # integer range so it can be addressed as unicode code points token_str = "".join(map(chr, np.maximum(flat - MIN_TOKEN, 0))) tokens = bpe_tokenizer(token_str)["input_ids"]
The whole pipeline is 158 lines of Python in processing_action_tokenizer.py, depending on nothing heavier than scipy and the tokenizers library. Using the released tokenizer takes four lines.
import numpy as np
from transformers import AutoProcessor
# FAST+, fitted on roughly 1M real robot action chunks
tokenizer = AutoProcessor.from_pretrained(
"physical-intelligence/fast", trust_remote_code=True
)
# expects actions already normalized to [-1, 1]
action_data = np.random.rand(256, 50, 14) # [batch, horizon, action_dim]
tokens = tokenizer(action_data) # list[list[int]]
decoded = tokenizer.decode(tokens) # back to [256, 50, 14]
print(np.mean([len(t) for t in tokens])) # tokens per chunkThe decoder needs the horizon and action dimension, because the token sequence does not encode its own shape. The tokenizer caches them from the last encode call, which works in a notebook and misbehaves in a serving loop where encode and decode run in different processes. Pass both to decode() explicitly when you deploy.
The defaults, and where paper and artifact disagree
The paper uses rounding scale 10 and BPE vocabulary size 1024 across its single-dataset experiments, and says the parameters are not very sensitive. The released tokenizer says something else. Its config, last modified 16 January 2025:
| Parameter | Paper, per-dataset | physical-intelligence/fast (FAST+) | lerobot-train-tokenizer default |
|---|---|---|---|
| DCT rounding scale | 10 | 10 | 10.0 |
| BPE vocabulary size | 1024 | 2048 | 1024 |
| min_token offset | not stated | -354 | learned during fit |
| Chunk length | 1 second of motion | set at call time | 10 (--action_horizon) |
| Normalization | quantile recommended | caller's job | QUANTILES |
| Encoded dimensions | all | all | "0:6,7:23" (--encoded_dims) |
| Chunks per episode | not stated | n/a | 0.1 (--sample_fraction) |
The vocabulary difference is not a typo. FAST+ covers single-arm, bi-manual and mobile manipulators at many control frequencies, so its coefficient range is wider. The negative min_token says the same: the smallest scaled coefficient during fitting was -354, and everything shifts by that to be addressable as a code point.
The encode path contains np.maximum(elem.flatten() - self.min_token, 0). Feed raw joint angles instead of values normalized to [-1, 1] and your coefficients land outside the fitted range. Anything below min_token is clamped to zero, silently: no exception, no warning, no log line. Training runs, loss falls, and reconstruction is garbage for exactly the chunks with the largest motion. Round-trip first and check the mean absolute error. If it is large, your normalization is wrong, not your model.
# run this before you spend money on a GPU
tokens = tokenizer(norm_chunks) # [B, H, D] in [-1, 1]
recon = tokenizer.decode(tokens, time_horizon=H, action_dim=D)
mae = np.abs(recon - norm_chunks).mean()
p99 = np.percentile([len(t) for t in tokens], 99)
print(f"round-trip MAE {mae:.4f} p99 tokens/chunk {p99:.0f}")
# MAE should be small relative to your action scale.
# p99 must stay below max_action_tokens (256 in lerobot pi0_fast).Fitting a tokenizer to your own SO-100 data
FAST+ works across action spaces, but the paper's own framing is that a tokenizer fitted to your data compresses better. lerobot ships a command, and fitting takes minutes rather than GPU hours.
- 1Install the pi extras
The FAST path sits behind the pi extra. Without it, an import error on scipy or tokenizers.
bashgit clone https://github.com/huggingface/lerobot.git cd lerobot pip install -e ".[pi]" - 2Fit the tokenizer on your dataset
--encoded_dims selects which dimension ranges to encode, which matters for bi-manual rigs. For a six-joint SO-100 it is "0:6".
bashlerobot-train-tokenizer \ --repo_id "yourname/so100-pick-place" \ --action_horizon 10 \ --encoded_dims "0:6" \ --vocab_size 1024 \ --scale 10.0 \ --normalization_mode QUANTILES \ --sample_fraction 0.1 \ --output_dir "./fast_so100" \ --push_to_hub \ --hub_repo_id "yourname/fast-so100" - 3Read the compression report
The script samples up to 1000 chunks and logs compression ratio, mean and p99 token length. Its ratio is (horizon x action_dim) over mean tokens.
textCompression Statistics: Average compression ratio: 4.31x Mean token length: 13.9 P99 token length: 24 Min token length: 8 Max token length: 31 - 4Train the policy against it
chunk_size and n_action_steps must match the horizon you fitted on, or the decoder reshapes into the wrong geometry.
bashlerobot-train \ --dataset.repo_id=yourname/so100-pick-place \ --policy.type=pi0_fast \ --policy.pretrained_path=lerobot/pi0fast-base \ --policy.action_tokenizer_name=yourname/fast-so100 \ --policy.chunk_size=10 \ --policy.n_action_steps=10 \ --policy.max_action_tokens=256 \ --policy.dtype=bfloat16 \ --policy.gradient_checkpointing=true \ --batch_size=4 --steps=100000 --policy.device=cuda
If the vocabulary is too small for the coefficient range, fit() raises an assertion rather than degrading quietly, and warns when the alphabet comes within 100 entries of it. Raise the vocabulary rather than lowering the scale: lowering the scale throws away real motion.

What tokens cost you at inference
This is the part lost when FAST gets called a straight win. Compression is a training-time win. At inference the policy emits its 30 to 60 tokens one forward pass at a time, and nothing removes that.
| Approach | What runs per chunk | Reported time | Source |
|---|---|---|---|
| Pi0 with flow matching | 10 denoising steps, batched | about 100 ms on a 4090 | FAST paper, VI-E |
| Pi0-FAST | 30 to 60 autoregressive token decodes | about 750 ms on a 4090 | FAST paper, VI-E |
| RT-2 PaLI-X 55B | 8 binned tokens, 55B model | 1 to 3 Hz | RT-2 paper |
| RT-2 5B variant | 8 binned tokens | about 5 Hz | RT-2 paper |
| RT-1 | 11 binned dimensions | 3 Hz inference | RT-1 paper |
750 ms is fine for a one-second chunk executed open loop, and not fine if you wanted to replan. lerobot softens the cost with KV-caching and greedy decoding at temperature 0.0, but sequential forward passes still equal token count. Same inference latency budget as in action chunking: a longer chunk amortizes latency but stales the plan.
- Reuses the pre-trained language model head unchanged, so any VLM becomes a VLA without surgery.
- Plain cross-entropy next-token training. No noise schedule, no sampler, no action expert.
- Pi0-FAST matched diffusion Pi0 on 10k hours of data with roughly 5x fewer GPU hours.
- The tokenizer is a small deterministic artifact you can round-trip and measure before training.
- FAST+ works as a black box across action spaces and control frequencies.
- Inference is serial in token count: about 750 ms per chunk against about 100 ms for flow matching.
- Quantization is lossy in a way invisible to the loss curve. Reconstruction error needs its own check.
- Token counts vary per chunk, so fast motions exceed max_action_tokens and get truncated while slow ones never do.
- Two extra hyperparameters, scale and vocabulary size, covered by no metric the trainer reports.
- Binning variants degrade badly above roughly 20 Hz, below many teleoperation recording rates.
Where the five trainable policies actually sit
Here is the honest part. If you are about to fine-tune something on an SO-100, tokenization is not your decision. Every policy on this platform predicts continuous actions at inference: no bin count and no FAST scale, because none of the five predicts tokens.
| Policy | Action representation at inference | Per action step | Tokenizer choice applies? |
|---|---|---|---|
| GR00T N1.7 | Diffusion action head over continuous actions | 152 ms | No |
| GR00T N1.5 | Diffusion action head over continuous actions | 165 ms | No |
| Pi0.5 | Flow matching action expert | 485 ms | Not at inference. FAST tokens sit in the vendor's pre-training only. |
| SmolVLA | Continuous action prediction | 245 ms | No |
| ACT | Direct continuous regression over a chunk | 20 ms | No. ACT never discretizes anything. |
That row deserves its footnote. The Pi0.5 paper (arXiv 2504.16054, 22 April 2025) states that during pre-training all tasks including robot actions are represented with discrete tokens, which leads to simple, scalable and efficient training, and that post-training adds an action expert for finer granularity and more compute-efficient inference, because discrete representations require expensive autoregressive decoding. FAST is in the ancestry of the Pi0.5 checkpoint you fine-tune, and out of the loop when you run it.

That is a design decision, not a missing feature. The tokenizer is only a lever when you build an autoregressive VLA from a language backbone, and for a six-joint arm at 30 Hz the defaults are already the useful settings. To compare the families on published benchmarks, the arena lists Pi0-FAST, Pi0 and Pi0.5.
Two routes to the same fine-tuned policy
The full manual path. Right if you want to change the tokenizer, swap the backbone or reproduce a paper number. Budget a day for the first run, mostly on CUDA versions and dataset conversions.
- 1Get a dataset in LeRobot format
Record your own or pull one from the hub. Check action dimension and frequency: both feed into token count.
bashhuggingface-cli download --repo-type dataset \ yourname/so100-pick-place --local-dir ./data/so100 - 2Fit or select a tokenizer
Fit on your data, or use lerobot/fast-action-tokenizer, fitted on over 1M real robot action sequences.
bashlerobot-train-tokenizer \ --repo_id yourname/so100-pick-place \ --action_horizon 10 --encoded_dims "0:6" \ --vocab_size 1024 --scale 10.0 \ --normalization_mode QUANTILES \ --output_dir ./fast_so100 - 3Rent a GPU and train
pi0_fast is PaliGemma-based: Gemma 2B with a SigLIP vision tower. openpi lists over 70 GB for full fine-tuning, over 22.5 GB for LoRA.
bashlerobot-train \ --dataset.repo_id=yourname/so100-pick-place \ --policy.type=pi0_fast \ --policy.pretrained_path=lerobot/pi0fast-base \ --policy.dtype=bfloat16 \ --policy.gradient_checkpointing=true \ --policy.chunk_size=10 --policy.n_action_steps=10 \ --policy.max_action_tokens=256 \ --steps=100000 --batch_size=4 --policy.device=cuda - 4Serve it and wire up the arm
You write the serving loop, camera plumbing, client-side normalization statistics and shutdown logic.
bashuv run scripts/serve_policy.py policy:checkpoint \ --policy.config=pi05_libero \ --policy.dir=checkpoints/pi05_libero/my_experiment/20000
Full control over tokenizer, backbone and training loop. If your question is about action representation, this is the only route that answers it.
The managed path skips the tokenizer question, because none of the five policies uses one. You pick the action head instead, and the training matrix turns that into a guide for your model and arm.
- 1Record episodes with the desktop client
Records LeRobot-format datasets with episodes, camera streams and joint states straight from a teleoperation session. Minimums: 50 episodes for GR00T N1.7, N1.5, Pi0.5 and ACT, 30 for SmolVLA.
- 2Pick by latency budget, not by tokenizer
ACT at 20 ms per action step is the only one comfortable in a tight reactive loop. GR00T N1.7 at 152 ms and Pi0.5 at 485 ms are pick-and-place.
- 3Submit the training form
The backend rents a spot GPU sized by required VRAM and writes checkpoints to object storage. GR00T N1.7 goes out at batch 32, lr 1e-4, 20000 steps; Pi0.5 at batch 1, lr 5e-5, 30000 steps.
- 4Run the policy back on the arm
Inference auto-provisions a pod serving the checkpoint. It carries an idle watchdog and destroys itself after an idle period, so nothing bills silently.
| Tier | Policies | Typical run | Typical cost |
|---|---|---|---|
| A100 or H100 80 GB | GR00T N1.7, GR00T N1.5, Pi0.5 | 3 to 6 h at 1.20 to 2.00 USD/h | about 4 to 12 USD |
| RTX 4090 or any 24 GB card | SmolVLA, ACT | 2 to 5 h at 0.30 to 0.60 USD/h | about 1 to 3 USD |
A LeRobot v3.0 dataset crashes the GR00T loader. GR00T N1.7 and N1.5 need v2.0 or v2.1, so v3.0 has to be converted down first. Pi0.5, SmolVLA and ACT all take v3.0. If a job stops on load, start at dataset rejected as v3.
Failure modes that come from the tokenizer
Most policy failures are data problems, not representation problems. A handful of symptoms point at the tokenizer, and they are worth recognising because they look like model failures.
- The arm holds its starting pose and drifts. Binning collapse: consecutive values fall in the same bin, so the model learned to copy.
- Motion is right in shape but visibly quantized. Bin resolution eaten by outliers, or a DCT scale so low the mid-frequency coefficients rounded to zero.
- Fast segments fail while slow segments work. Fast motion means more non-zero coefficients, more tokens, and hits the max_action_tokens ceiling first. Check the p99.
- The policy stops mid-motion and resumes at the next chunk. A decode failure that silently returned a zero chunk. See policy freezes mid-motion.
- Reconstruction is fine locally and terrible in the serving loop. The decoder is using a cached shape from a different call.
Read lerobot's decode_actions_with_fast before trusting it on hardware. If the BPE decode raises, the handler logs a warning and substitutes np.zeros((time_horizon, action_dim)) for the coefficients. The inverse DCT of zeros is zeros, so the robot gets an all-zero chunk and the arm stops for one chunk duration. With relaxed_decoding=True, the default, short sequences are zero-padded on the right instead of failing. Count those warnings during evaluation: if the count is not zero, your success rate includes runs where the policy did nothing.

How to decide
Autoregressive VLA from a language backbone, data above about 20 Hz: use FAST, not binning. The paper's 20 Hz and 50 Hz results show binning making no progress. On 5 Hz data binning is defensible. With a working continuous action head, tokenization is a training-speed argument against an inference-speed penalty, which fits pre-training and not the last mile. Fine-tuning one of the five here: spend the attention on recording better episodes instead.
One caveat applies to every route. The control loop here runs at 20 to 485 ms per action step, and inference has to sit next to the servos for anything fast. Public-internet round trips on top of a 485 ms Pi0.5 step turn a working policy into a hesitant one. Remote inference suits slow pick-and-place, not fast reactive motion. Background in our overview of VLA models and the Pi0 flow matching write-up.
Five policies, real latency numbers, no tokenizer homework
GR00T N1.7, GR00T N1.5, Pi0.5, SmolVLA and ACT compared on parameters, GPU tier, per-step latency and the minimum number of episodes each needs before it does anything useful.
Compare the policiesWhat is action tokenization in a vision-language-action model?▾
The mapping between the discrete symbols a transformer predicts and the continuous joint targets a robot executes. An autoregressive model can only emit indices into a fixed vocabulary, so a trajectory is encoded as indices and decoded back. Diffusion and flow matching heads skip this entirely.
How does FAST differ from 256-bin discretization?▾
Binning assigns one token per dimension per timestep, so token count grows with control frequency. FAST runs a discrete cosine transform over the time axis, rounds the coefficients with a scale factor of 10, then compresses the sparse integers with byte pair encoding. On 50 Hz T-shirt folding data the paper reports 53 tokens per chunk against 700 for binning.
Is FAST faster at inference than diffusion?▾
No, slower. The paper reports about 750 ms per chunk for Pi0-FAST against about 100 ms for diffusion Pi0 on a 4090, because the autoregressive model decodes 30 to 60 tokens sequentially while diffusion runs 10 batched steps. FAST's advantage is training time: roughly 5x fewer GPU hours on 10k hours of data.
Which tokenizer should I use for a six-joint SO-100 arm?▾
Start with lerobot/fast-action-tokenizer, fitted on over 1M real robot action sequences. Then fit your own with lerobot-train-tokenizer using --encoded_dims "0:6" and compare compression ratio and p99 token length. Fitting takes minutes, so measure both.
Do the policies on AY-Robots let me choose a tokenizer?▾
No, and none needs one. GR00T N1.7 and N1.5 use a diffusion action head, Pi0.5 a flow matching action expert, SmolVLA and ACT predict continuous actions directly. FAST tokens appear in Pi0.5's ancestry from the vendor's pre-training, but not when you fine-tune or run the checkpoint.
Why does my tokenized policy train to a low loss but not move?▾
Almost always because the token distribution is dominated by repeats. At high control frequencies consecutive joint values land in the same bin, so predicting the previous token is usually correct: accuracy looks excellent while trajectory quality is worthless. Round-trip through the tokenizer rather than trusting the loss curve.
Sources
- FAST: Efficient Action Tokenization for Vision-Language-Action Models
- physical-intelligence/fast: the FAST+ universal action tokenizer
- LeRobot documentation: Pi0-FAST
- RT-1: Robotics Transformer for Real-World Control at Scale
- RT-2: Vision-Language-Action Models Transfer Web Knowledge to Robotic Control
- OpenVLA: An Open-Source Vision-Language-Action Model
- Pi0.5: a Vision-Language-Action Model with Open-World Generalization
- Physical-Intelligence/openpi: reference implementation and checkpoints
Sources
- FAST: Efficient Action Tokenization for Vision-Language-Action Models (Pertsch et al., 16 Jan 2025)
- Physical Intelligence: FAST: Efficient Robot Action Tokenization
- physical-intelligence/fast: FAST+ universal action tokenizer, config and source
- lerobot/fast-action-tokenizer: FAST+ tokenizer packaged for LeRobot
- LeRobot documentation: Pi0-FAST training, tokenizer fitting and LIBERO results
- huggingface/lerobot: pi0_fast configuration and lerobot_train_tokenizer source
- Physical-Intelligence/openpi: pi0_fast_base checkpoints and hardware requirements
- RT-1: Robotics Transformer for Real-World Control at Scale
- RT-2: Vision-Language-Action Models Transfer Web Knowledge to Robotic Control
- OpenVLA: An Open-Source Vision-Language-Action Model
- Pi0.5: a Vision-Language-Action Model with Open-World Generalization
- Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware (ACT)
- lerobot/pi0fast-base: the base checkpoint used for Pi0-FAST fine-tuning
- scipy.fft.dct: the discrete cosine transform FAST is built on
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started