[Doc] add tutorial on collector trajectory assembly internals - #3600
Conversation
Closes pytorch#3588 - Explains split_trajectories(), _traj_ingest(), _traj_emit() - Includes edge case of trajectory spanning multiple batches - Covers mask semantics, padded vs nested outputs, and troubleshooting - Follows TorchRL documentation style
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/rl/3600
Note: Links to docs will display an error until the docs builds have been completed. ❗ 1 Active SEVsThere are 1 currently active SEVs. If your PR is affected, please view them below: This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
| Prefix | Label Applied | Example |
|---|---|---|
[BugFix] |
BugFix | [BugFix] Fix memory leak in collector |
[Feature] |
Feature | [Feature] Add new optimizer |
[Doc] or [Docs] |
Documentation | [Doc] Update installation guide |
[Refactor] |
Refactoring | [Refactor] Clean up module imports |
[CI] |
CI | [CI] Fix workflow permissions |
[Test] or [Tests] |
Tests | [Tests] Add unit tests for buffer |
[Environment] or [Environments] |
Environments | [Environments] Add Gymnasium support |
[Data] |
Data | [Data] Fix replay buffer sampling |
[Performance] or [Perf] |
Performance | [Performance] Optimize tensor ops |
[BC-Breaking] |
bc breaking | [BC-Breaking] Remove deprecated API |
[Deprecation] |
Deprecation | [Deprecation] Mark old function |
[Quality] |
Quality | [Quality] Fix typos and add codespell |
Note: Common variations like singular/plural are supported (e.g., [Doc] or [Docs]).
|
Hi @vmoens, it would be great to get some feedback. Thanks. |
vmoens
left a comment
There was a problem hiding this comment.
Thanks for this!
I think the goal was not only to do this but also cover recent new features such as
- collectors that yield fully built trajectories
- populating replay buffers with these within the buffer.
Another item that needs to be thoroughly documented here is the done/truncated handling in split_trajectories(). Eg, if a trajectory is incomplete, what do we do with its last truncated value?
There are also some efficiency considerations (eg, using nested-tensors instead of padding, there's a kwarg in split_trajectories for that).
More generally, the tutorial should be more written in plain english, with intro ("in this tutorial you will learn ...") and conclusion ("we have covered ..." , "useful resources: X, Y, Z in tutorials and documentation).
Internal buffering (private features like _traj_ingest and such) should not be part of the public doc.
Closes pytorch#3588 - Explains split_trajectories(), trajs_per_batch, replay buffer usage - Covers mask semantics, done vs truncated, padded vs nested outputs - Follows TorchRL documentation style
|
Hi @vmoens, Thank you very much for the detailed feedback! I have updated the tutorial based on your comments:
The tutorial is now focused only on public APIs and practical usage. Looking forward to your feedback. Thanks again |
…ajectory-assembly
vmoens
left a comment
There was a problem hiding this comment.
Let's not use print() statements but plain sphinx gallery sections.
I find the explanation pretty shallow. A tutorial should be a simple, realistic example (training, eval, ...) where we show how we're using a specific feature to solve a given problem.
The synthetic data here is a bit hard to understand. Ideally we'd like data that was generated from a real env, show what the data looks like, then move on to show what happens if we don't assemble trajectories and what we can do if we assemble them, then perhaps show a concrete example of what this enables.
Last point: we should register this in the list of tutorials in the index otherwise the tutorial is invisible in the docs
Closes pytorch#3588 - Explains split_trajectories(), trajs_per_batch, and replay buffer usage - Covers mask semantics, done vs truncated handling, padded vs nested outputs - Uses real environment example and plain Sphinx gallery sections - Follows TorchRL documentation style
Closes pytorch#3588 - Explains split_trajectories(), trajs_per_batch, and replay buffer usage - Covers mask semantics, done vs truncated handling, padded vs nested outputs - Uses real environment example and plain Sphinx gallery sections - Follows TorchRL documentation style
There was a problem hiding this comment.
I have now removed the old file coding_dqn.py completely.
Only the clean collector_trajectory_assembly.py remains.
There was a problem hiding this comment.
I'm not sure I'm following, why do we need to delete anything?
There was a problem hiding this comment.
Sorry for the confusion.
I saw that coding_dqn.py contained my earlier code with private internals (_traj_ingest, _traj_emit) and many print() statements.
So I removed it to keep only the clean version collector_trajectory_assembly.py.
Closes pytorch#3588 - Explains split_trajectories(), trajs_per_batch, and replay buffer usage - Covers mask semantics, done vs truncated handling, padded vs nested outputs - Uses real environment example and plain Sphinx gallery sections - Follows TorchRL documentation style
…n.py - Rewrite tutorial to use real env data (GymEnv + SyncDataCollector) instead of synthetic TensorDict, replace print headers with Sphinx Gallery RST sections, and register in docs index - git rm _version.py (auto-generated by setuptools_scm), add to .gitignore, and add pre-commit hook to prevent future commits Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ng_dqn.py Merge remote branch, resolve conflicts: - Keep _version.py deleted (auto-generated, must not be tracked) - Keep our rewritten tutorial (real env data, no synthetic TensorDict) - Restore coding_dqn.py that was accidentally deleted by remote Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show how passing a replay buffer to the collector and calling start() enables fully asynchronous background collection, including with trajs_per_batch for complete trajectory batches. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The replay buffer in the collector.start() example now uses a
SliceSampler(slice_len=16, end_key=("next", "done")) to sample
contiguous sub-sequences that respect episode boundaries,
showcasing the natural fit with complete trajectory storage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add seealso in dqn_with_rnn.py pointing to the collector trajectory assembly tutorial for details on split_trajectories, trajs_per_batch, SliceSampler, and async collection. Also fix broken RNN tutorial cross-ref in collector_trajectory_assembly.py. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The "Storing trajectories in a replay buffer" section now uses a SliceSampler so sampled batches are contiguous sub-sequences rather than isolated transitions. Added seealso linking to the replay buffer tutorial's trajectory storage section for more detail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@coder-jayp I restored the dqn tutorial and edited the trajectory one. Can you give it a look? |
SliceSampler operates on flat transition storage and uses
end_key to locate episode boundaries. Extending the buffer with
pre-assembled (trajs, max_len) tensors causes a shape error
("Expected the end-of-trajectory signal to be 1-dimensional").
Fix both the replay buffer section and the async collector.start()
section to extend with flat collector batches instead of
trajs_per_batch output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks @vmoens. Really appreciate it. |
Closes #3588
Description
This PR adds a new tutorial: "TorchRL Collectors Deep Dive: Trajectory IDs, Partial Chunks, and Emission".
The tutorial explains the internal mechanics of how TorchRL collectors handle trajectories, which is especially important for users training recurrent or sequence-based policies.
What it covers
split_trajectories()reassembles, pads, and masks trajectories_traj_ingest()and_traj_emit()("collector", "traj_ids")and("collector", "mask")done/terminatedboundary handlingas_nested=True(with performance comparison)The tutorial includes fully runnable code examples and follows the existing TorchRL documentation style.
Motivation and Context
Users training recurrent or sequence-based policies (RNNs, GRUs, LSTMs, Transformers, etc.) frequently need to understand how TorchRL collectors turn raw batches into clean trajectories.
The current documentation shows how to use the collectors, but does not explain the internal dataflow — specifically why trajectories are split across batches, how partial trajectories are buffered and reassembled, and the exact meaning of
("collector", "traj_ids")and("collector", "mask").This tutorial fills that gap with clear explanations, runnable examples, and an edge case where a trajectory spans multiple collector iterations.
Types of changes
Checklist