Repository navigation
[python] Preserve source LeRobot Episode statistics - #11082
XiaoHongbo-Hope wants to merge 3 commits into
Conversation
5b70d03 to
b4618d7
Compare
| stats = {} | ||
| for name in _CONTROLS: | ||
| parts = [values[name] for values in plan["control_stats"].values() | ||
| if name in values] |
There was a problem hiding this comment.
Could we make the episode_index entry use the combined reader’s coordinates before storing these statistics? _transform_frames intentionally keeps frame episode_index values source-local, while _SourceLocalReader.read_indices adds each source’s Episode offset. With the existing two-source fixture, the reader returns [0,0,1,1,1,2,2,3,3,3], but meta.stats["episode_index"]["mean"] is 0.6 instead of 1.6 (and its min/max/std are likewise source-local). Computing the Episode statistic column with plan["episode_offset"] while leaving the stored frame column unchanged fixes both local and Ray imports. Could we also update the regression assertion to compare against the reader-visible Episode IDs?
JingsongLi
left a comment
There was a problem hiding this comment.
Requirement fit: SUPPORTED. Implementation: FINDINGS. Preserving original Episode statistics and quantiles separately from training-view controls has direct data round-trip value.
Reviewed all four files and local/Ray publication, legacy fallback and schema evolution. 384 selected LeRobot import/reader/writer/text-column tests passed, with 2 platform/dependency skips; project flake8 and diff whitespace checks passed. A parent-version writer/current reader probe reproduces the backward-compatibility failure below (unrelated-field control passes). The existing episode-coordinate statistics comment also remains relevant; the underlying local-coordinate calculation predates this diff. Current GitHub metadata reports merge conflicts, so UUID/VARIANT master changes also need reconciliation and revalidation before landing.
| for source in sources: | ||
| raw = source.get("read_control_stats") | ||
| if raw: | ||
| decoded_rows.append(json.loads(raw)) |
There was a problem hiding this comment.
[P2] Distinguish internal statistics from existing user text columns
read_control_stats was a valid public extra_dataset_fields name before this change, but the reader now interprets any column with that name as internal statistics. Using the exact parent writer, I imported a source with extra_dataset_fields={'read_control_stats': 'notes.txt'} containing ordinary text; the parent can read the resulting group, while this head's PaimonLeRobotDataset raises JSONDecodeError here. The same import with field name notes remains readable. This breaks the stated existing-group compatibility even without appending or changing any files. Use distinguishable internal metadata/versioning (and preserve historical user columns), rather than selecting this representation solely by an unreserved column name.
b4618d7 to
63642b1
Compare
Importing multiple LeRobot sources rewrote Episode control statistics and dropped source quantiles even though stored frames kept source-local IDs. This preserves original Episode
statsVARIANT and stores derived training-view controls in a marked internal Dataset column.The training reader computes
episode_indexstatistics in reader-visible coordinates. Existing user text columns namedread_control_statsremain readable after append. If a legacy user column has the exact internal column name without its marker, append fails before writing instead of silently publishing incorrect training statistics.Validation: 392 LeRobot import, reader, writer, and text-field tests passed; 1 skipped. Flake8 on changed Python files and
git diff --checkpassed.