Repository navigation
fix(serving): keep the state float32 for delta-action targets - #559
Merged
Merged
Conversation
Inference entry points built `state` in the bfloat16 serving dtype, so a delta-action checkpoint re-anchored its predicted deltas on a rounded state (up to 2**-7 rad on a joint in [2, 4) rad). The dataset formed the training deltas against the float32 state, so the entry points now send float32 and `Normalize` computes in its stats' dtype, keeping the model input bit-identical to training. State projections cast to their own weight dtype. Also make `actions_mse_loss.py` compare delta checkpoints in delta space and fix its chunk indexing, action-width lookup and `r2_score` argument order.
…s-981d64 # Conflicts: # CHANGELOG.md
Contributor
|
[claude-review] summary for commit 3807c6f No blocking issues found. |
shuheng-liu
marked this pull request as ready for review
October 6, 2026 17:16
This was referenced Oct 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Fixes served joint targets for delta-action checkpoints (🐛 Bug).
preprocess_observationforeval.pyand in-training sim eval, and the dummy observations ofinference.py/benchmark_inference.py/high_level_planner_inference.py) builtstatein the bfloat16 serving dtype. A delta-action checkpoint (delta_action_state_mapset) adds that state back onto its predicted deltas, but the dataset formed the training deltas against the float32 state. So every absolute target carried the state's bf16 rounding: up to 2**-7 ≈ 0.0078 rad (0.45°) on a joint in [2, 4) rad, re-applied on every chunk.stateand the gRPC RTCprefix_actionare now built atINFERENCE_STATE_DTYPE(float32).BaseDataset._to_standard_data_formatcasts every float to bf16 after forming the deltas, andNormalizethen works in bf16 arithmetic. A float32 state would have normalized in float32 and moved a discretized state token by a bin for 16–60% of states, depending on the stats. SoNormalizenow casts a floating input to its stats' dtype. That is a no-op in training, and a served policy's normalized input stays bit-identical.cast_to_weight_dtype) instead of a hard-coded bf16. pi0 had no cast at all, so a float32 state crashed it.add_chunk_start_state/subtract_chunk_start_statenow compute in the wider of their two input dtypes.scripts/actions_mse_loss.pyscored a delta checkpoint's absolute predictions against delta targets; it now compares in delta space. This also fixes three older bugs:chunk_size > 1;KeyErroron datasets whose action column is namedaction;r2_scorecalled with its arguments swapped.Served actions change only for delta-action checkpoints, plus
xr1/flux3_action, which leavestateunnormalized and now preprocess it at float32, as their reference pipelines do. Both fixes have CHANGELOG entries under[Unreleased].How it was tested
tests/policies/test_inference_state_precision.pydrives the realRobotPolicyServicer.GetActionChunkand the RoboCasainfer/infer_batchagainst a realPI05Policy, with only the Hub-loaded pieces stubbed. It asserts:state + delta, bit for bit;It also covers
Normalize,cast_to_weight_dtypeand pi0, plus an AST sweep that fails if any script buildsstateat another dtype.tests/scripts/test_actions_mse_loss.pyruns a perfect-policy stub on a tiny delta dataset. There are also additions totests/datasets/test_action_indexing.pyandtests/envs/test_utils.py.Mutation check: reverting each piece of the fix fails exactly the tests that pin it.
CPU suite, run as
cpu_test.ymlruns it: 3699 passed, 14 skipped. Pre-commit is clean.Determinism (CLAUDE.md rule 3):
configs/dev/ci_config.json, 3 steps on CPU, same seed. Per-micro-batch losses (exact float hex) were bit-identical across two runs of this branch and one run of the base commit. With--policy.state_type=continuous, the first forward loss was bit-identical to the base commit.GPU pytests (
pytest -m "gpu") and regression tests have not been run. They are deferred to the nightlygpu_test.yml/regression_test.yml, and the GPU checkbox below stays unticked until they pass.How to checkout & try? (for the reviewer)
Checklist
Note: Before submitting this PR, please read the contributor guideline.