docs(tutorials): add end-to-end walkthrough#618
Conversation
A new tutorial that takes Qwen3-1.7B, the OpenEnv `reasoning_gym_env`, and TRL, and runs the full pipeline end-to-end: define the env wrapper, train with GRPO via `environment_factory`, publish to Hub, and read the reward delta from `trainer.state.log_history`. The page is paired with a runnable Colab notebook at `examples/grpo_reasoning_gym/end_to_end_walkthrough.ipynb` (generated from the markdown via jupytext) and linked from the tutorials index. Comms beat: a single page where readers see the metric move from a real baseline to a real post-training number on a procedural task — no hand-waving. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR adds a new end-to-end tutorial covering
Confidence Score: 3/5Not safe to merge as-is — the notebook raises a NameError on first execution due to undefined MODEL_NAME. Two P1 defects (undefined MODEL_NAME causing NameError at runtime, and a max_steps code/prose mismatch) prevent the tutorial from working correctly out of the box. These are straightforward fixes but must be resolved before the tutorial can serve its purpose. Both docs/source/tutorials/end-to-end-walkthrough.md and examples/grpo_reasoning_gym/end_to_end_walkthrough.ipynb carry the same bugs and need to be updated in sync. Important Files Changed
Sequence DiagramsequenceDiagram
participant User as User (Colab)
participant Trainer as GRPOTrainer (TRL)
participant Env as ReasoningGymTrainEnv
participant Space as HF Space (reasoning_gym)
participant Hub as Hugging Face Hub
User->>Trainer: trainer.train()
loop Per generation batch
Trainer->>Env: env.reset(**row)
Env->>Space: client.reset(dataset_name, config, seed, size)
Space-->>Env: observation.question
Env-->>Trainer: question string
Trainer->>Trainer: Generate num_generations completions
Trainer->>Env: env.answer(answer)
Env->>Space: client.step(ReasoningGymAction)
Space-->>Env: observation.score, correct_answer
Env-->>Trainer: feedback string + env.reward
Trainer->>Trainer: GRPO advantage computation and policy update
end
Trainer-->>User: trainer.state.log_history
User->>Hub: trainer.push_to_hub()
Prompt To Fix All With AIThis is a comment left during a code review.
Path: docs/source/tutorials/end-to-end-walkthrough.md
Line: 251-258
Comment:
**`MODEL_NAME` is undefined — `NameError` at runtime**
`GRPOTrainer(model=MODEL_NAME, ...)` references a variable `MODEL_NAME` that is never defined anywhere in the tutorial. The model identifier `"Qwen/Qwen3-1.7B"` is only mentioned in prose; no cell assigns it to a Python variable. Anyone who runs the notebook top-to-bottom will hit a `NameError` before training even starts.
```suggestion
MODEL_NAME = "Qwen/Qwen3-1.7B"
trainer = GRPOTrainer(
model=MODEL_NAME,
reward_funcs=reward_func,
train_dataset=dataset,
args=grpo_config,
environment_factory=ReasoningGymTrainEnv,
)
trainer.train()
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: docs/source/tutorials/end-to-end-walkthrough.md
Line: 241
Comment:
**`max_steps` mismatch between code and prose**
The `GRPOConfig` block sets `max_steps=150`, but the explanatory paragraph immediately below says "`max_steps=100` caps the run before saturation." Readers following the prose rationale will be confused about which value is actually in effect. The note about saturation behaviour should reference the value actually in the code (`150`). The same paragraph also says "section 10" for the Hub push but that step is section 9.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: docs/source/tutorials/end-to-end-walkthrough.md
Line: 294-301
Comment:
**`statistics.mean` will crash on an empty list**
If training is interrupted or fewer than 1 log entry contains `"reward"`, `rewards` will be empty and `statistics.mean([])` raises `StatisticsError: mean requires at least one data point`. A simple length guard would prevent a confusing traceback for beginners who interrupt the run early.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: docs/source/tutorials/end-to-end-walkthrough.md
Line: 48
Comment:
**Installing from `@main` of transformers pins to an unstable branch**
`!pip install -q git+https://github.com/huggingface/transformers.git@main` installs the current tip of `main`, which changes daily. For a tutorial meant to be reproducible, pinning to a release tag or PyPI version (e.g., `transformers>=4.51.0`) is strongly preferred.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "docs(tutorials): add end-to-end GRPO wal..." | Re-trigger Greptile |
- Define `MODEL_NAME` before the `GRPOTrainer` cell so the notebook runs top-to-bottom without `NameError` (was only mentioned in prose after the eval section was simplified to use `trainer.state.log_history`). - Sync prose under the GRPO config block: `max_steps=150` matches the code, and the Hub push is in section 9 (not 10). - Guard the reward-delta computation against empty `rewards` lists so early kernel interrupts don't surface a `StatisticsError` traceback. - Replace the `transformers @main` install with a `>=5.3.0` PyPI pin — any 5.3+ release has the `environment_factory` integration TRL needs, and we want the tutorial reproducible. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Darktex
left a comment
There was a problem hiding this comment.
Note: This is an automated review by Claude Code, not a human review.
Alignment Review Report
Automated Checks
- Lint: PASS (pre-existing issues in unrelated files)
- Debug code: CLEAN (PR scope)
Tier 1: Fixes Required
-
docs/source/tutorials/end-to-end-walkthrough.mdandexamples/grpo_reasoning_gym/end_to_end_walkthrough.ipynb—{note}blocks are MyST-Sphinx directives. They render correctly in Sphinx docs but appear as raw fenced code blocks (```{note} ... ```) in Jupyter/Colab. Since there is a prominent "Open in Colab" badge at the top, notebook readers will see broken formatting on all four note blocks. Use plain Markdown> **Note:** ...callouts inside the notebook cells, and keep{note}only in the.mdsource.
Tier 2: Alignment Discussion
None identified. The tutorial:
- Keeps rewards inside the environment (
result.observation.scoreread fromenv.step, stored asself.reward— no external computation). - Respects client-server separation (imports only from
reasoning_gym_envpublic surface:ReasoningGymEnv,ReasoningGymAction). - Does not expose
reset()or simulation controls to the model-under-training. - Uses the established
environment_factorypattern consistent with the Wordle GRPO tutorial.
Additional Polish
The tutorial acknowledges that num_generations=2 is low and that reward_std may hit persistent zero — but the warning appears in section 8's prose, not adjacent to the config value in section 7 where a reader would naturally look for guidance. A one-line comment (# low for memory; raise to 4+ for better advantage signal) on the num_generations=2 line would help readers catch this before training.
Summary
- 1 issue to fix (MyST admonitions break in Colab notebook)
- 0 alignment points for human review
Automated review by Claude Code | Learn more
Darktex
left a comment
There was a problem hiding this comment.
Note: This is an automated review by Claude Code, not a human review.
Alignment Review Report
Automated Checks
- Lint: PASS for PR scope. Pre-existing formatting issues in
envs/chat_env/,envs/repl_env/,envs/textarena_env/, andsrc/openenv/cli/are untouched by this PR. - Debug code: CLEAN for PR scope. Pre-existing
printstatements insrc/openenv/core/containers/test_local_docker_provider.pyand TODOs insrc/openenv/cli/are untouched by this PR.
Tier 1: Fixes Required
-
examples/grpo_reasoning_gym/end_to_end_walkthrough.ipynb(cells containing{note}) - MyST admonition syntax ({note}) is a Sphinx-only directive. In Colab and standard JupyterLab it renders as a fenced code block with{note}as the language specifier, not as a styled callout. Since Colab is the primary audience for.ipynbtutorials, these four note blocks should be converted to plain Markdown blockquotes (e.g.> **Note:** ...) so they render correctly in both Sphinx (via the.mdsource) and Colab (via the.ipynbcopy). The.mdsource can keep{note}as-is since it is processed by Sphinx.
Tier 2: Alignment Discussion
ALIGNMENT FLAG: External reward_func reads env.reward from a client-side wrapper attribute
- Principle at stake: "Rewards inside environment" (PRINCIPLES.md, RFC 002)
- The concern: The tutorial introduces
reward_func(environments, **kwargs) -> list[float]as a top-level function that readsenv.rewardfrom theReasoningGymTrainEnvwrapper. The reward value itself is computed server-side (arrives viaresult.observation.score), but the indirection through a client-side attribute and an external function is a new teaching pattern. For this tutorial it is benign - the score is computed by the server and merely cached on the wrapper for the TRL callback. However, canonicalizing this pattern in the docs means future tutorial authors may copy it and inadvertently move reward computation logic into the externalreward_funcbody rather than inside the environment. The concern is about what we are teaching, not about this specific instance. A brief inline callout explaining why the reward is safe here (server computed, client just caches) would prevent cargo-culting. - Suggested reviewer: @Darktex
ALIGNMENT FLAG: Hardcoded personal HF Space URL as the default endpoint
- Principle at stake: "Be hands-on: Provide ready-to-use implementations" and production-readiness (PRINCIPLES.md)
- The concern:
base_url="https://sergiopaniego-reasoning-gym.hf.space"andgit+https://huggingface.co/spaces/sergiopaniego/reasoning_gymare personal Space URLs in the code that readers copy-paste and run verbatim. The tutorial prose correctly notes these are rate-limited and instructs readers to deploy their own copy, but the code block default leaves personal infrastructure as the load-bearing path for every tutorial run. If the Space goes down, scales down, or is modified, all tutorial runs silently break. Consider whether there is an org-owned Space (e.g.meta-pytorch/reasoning_gym) that should be the canonical default, with the personal Space noted as the historical demo. - Suggested reviewer: @Darktex
Summary
- 1 mechanical issue to fix (MyST note syntax in
.ipynbrenders as raw code in Colab) - 2 alignment points for human review (reward pattern pedagogy, hardcoded personal Space URL)
Automated review by Claude Code | Learn more
Darktex
left a comment
There was a problem hiding this comment.
Note: This is an automated review by Claude Code, not a human review.
Summary
Well-written tutorial, structurally sound, imports and API calls match the current reasoning_gym_env public surface exactly. One quality issue: MyST directive fences inside the Jupyter notebook cells will not render in Colab/Jupyter and should be converted to plain markdown callouts.
Tier 1 — Bugs / Quality
-
examples/grpo_reasoning_gym/end_to_end_walkthrough.ipynb— Three markdown cells contain MyST-style```{note}fences (e.g. the "T4 won't fit" note, the "Replace the base_url" note, the "chat_template_kwargs" note, and the "delta is measured during training" note). MyST directives are processed by Sphinx during docs builds but Jupyter/Colab renders them as literal fenced code blocks, so readers opening the notebook in Colab see ugly raw-text boxes instead of rendered callouts. Fix: convert each```{note}\n...\n```block in the notebook to a plain> **Note:** ...blockquote. The.mddoc file can keep the{note}directives because it is Sphinx-rendered only. -
docs/source/tutorials/end-to-end-walkthrough.mdline 47:!pip install -q --no-deps git+https://huggingface.co/spaces/sergiopaniego/reasoning_gyminstalls directly from a personal HF Space (not the canonicalopenenv-corepackage path). The tutorial body already warns readers to substitute their own deployment, but the hardcoded personal Space URL in the primary install cell will silently break for any reader whose Space clone diverges or is deleted. Consider replacing with!pip install -q --no-deps git+https://github.com/meta-pytorch/OpenEnv#subdirectory=envs/reasoning_gym_env(or a PyPI release once available) and reserving the Space install for a clearly-labelled "shortcut" note.
Tier 2 — Alignment
- The
reset()andstep()calls inReasoningGymTrainEnvare invoked by the TRL trainer (training orchestration), not by the agent being trained — this is the correct split and does not violate the "agents cannot reset" invariant. No flag needed. reward_funcreadsenv.reward, which was set insideanswer()fromresult.observation.scorereturned byenv.step()— reward computation stays inside the environment boundary. Aligned with RFC 002.- Client imports are from
reasoning_gym_envpublic surface (__init__.py), no server-side imports. Aligned with the client-server separation invariant. - The tutorial acknowledges that the reward delta metric is a training-curve shortcut and explicitly flags the held-out eval path (via harness, #471) as follow-up work. Aligned with the "honest about limitations" expectation in docs.
Verdict
Two concrete quality fixes requested: MyST directives in the notebook (renders badly in Colab) and the hardcoded personal Space URL in the install cell. No invariant or alignment issues.
Automated review by Claude Code | Learn more
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Enriches the "Δ ≈ 0 pp, initial very low" diagnostic with a note about format compliance as the likely bottleneck and a link to the SFT warm-up tutorial. Adds a "Use SFT as a warm-start" bullet to the "Where to go next" section. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
burtenshaw
left a comment
There was a problem hiding this comment.
Approved per maintainer merge request after required checks passed.
Summary
Adds an end-to-end tutorial that goes from
pip installto a trained model in one page. It usesreasoning_gym_env(the OpenEnv wrapper around the Reasoning Gym library) as the environment, Qwen3-1.7B as the base model, and TRL'sGRPOTrainerwith theenvironment_factorypattern for training. The accompanying notebook lives atexamples/grpo_reasoning_gym/end_to_end_walkthrough.ipynband is generated from the markdown.This is a first version. Once #471 is merged, some parts can be updated — in particular the evaluation, which today reads the reward delta from
trainer.state.log_historyand can be replaced by a held-out pass through the harness.Type of Change
Alignment Checklist
Before submitting, verify:
.claude/docs/PRINCIPLES.mdand this PR aligns with our principles.claude/docs/INVARIANTS.mdand no invariants are violated/pre-submit-pr(orbash .claude/hooks/lint.shand tests) and addressed all issuesRFC Status
Test Plan
Claude Code Review
@adithya-s-k @burtenshaw