Repository navigation
Training engine: buffer metrics on the host - #6017
Closed
igorts-git wants to merge 1 commit into
Closed
igorts-git wants to merge 1 commit into
igorts-git wants to merge 1 commit into
Conversation
igorts-git
force-pushed
the
port/pr1-metrics-checkpointing
branch
2 times, most recently
from
October 28, 2026 23:50
b413bef to
dd375e2
Compare
4 tasks done
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
SurbhiJainUSC
force-pushed
the
igorts/tunix-dist-rl-api
branch
2 times, most recently
from
October 29, 2026 16:35
3e61343 to
9cf01be
Compare
igorts-git
force-pushed
the
port/pr1-metrics-checkpointing
branch
from
October 29, 2026 18:10
dd375e2 to
0053443
Compare
copybara-service
Bot
deleted the branch
AI-Hypercomputer:igorts/tunix-dist-rl-api
October 29, 2026 21:48
igorts-git
force-pushed
the
port/pr1-metrics-checkpointing
branch
from
October 30, 2026 03:53
0053443 to
49e5c89
Compare
4 tasks done
igorts-git
added a commit
to igorts-git/maxtext
that referenced
this pull request
Oct 30, 2026
- MetricsRecorder keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - update() flushes the step's metrics before the optimizer step, so an unconvertible value raises with nothing applied. - record_metrics skips intermediate_outputs and tuple/list aux values. Differences from atwigg/mlperf: - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: MetricsRecorder.restore_buffers, weighted_metric_bounds and the metric_bounds checkpoint metadata, the engine's _restore_metrics_buffer and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - The pre-step flush is added to PR 5999's explicit update(self); MLPerf's update(self, **kwargs) is not adopted. Co-authored-by: Param Bole <parambole@google.com> Fixes AI-Hypercomputer#6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 70 passed. Covers Python-list buffering and the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, the single-stack flush, and the pre-update flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files).
igorts-git
force-pushed
the
port/pr1-metrics-checkpointing
branch
from
October 30, 2026 16:38
49e5c89 to
db6c0a4
Compare
copybara-service Bot
pushed a commit
that referenced
this pull request
Oct 30, 2026
Imported from GitHub PR #6017 Stacked on top of #6038 (PR 0). # Description Changes the training engine's `MetricsRecorder` from appending to JAX arrays on every micro-batch to buffering metrics in host-side Python lists and building the arrays once per step, at flush. Why: the eager `jnp.append` path dispatched one device op per metric per micro-batch (about 100 metrics for GRPO). The new flush is one `jnp.stack` per metric per step, independent of the micro-batch count. Changes: - `MetricsRecorder` keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - `update()` flushes the step's metrics before the optimizer step, so an unconvertible value raises with nothing applied. - `record_metrics` skips `intermediate_outputs` and tuple/list aux values. ## Differences from `atwigg/mlperf` - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: `MetricsRecorder.restore_buffers`, `weighted_metric_bounds` and the `metric_bounds` checkpoint metadata, the engine's `_restore_metrics_buffer` and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - The pre-step flush is added to PR 5999's explicit `update(self)`; MLPerf's `update(self, **kwargs)` is not adopted. ## Attribution Ported from Param Bole's #5568 on `atwigg/mlperf`. Co-authored-by: Param Bole <parambole@google.com> Fixes #6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 70 passed. Covers Python-list buffering and the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, the single-stack flush, and the pre-update flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files). PiperOrigin-RevId: 1009954644
igorts-git
added a commit
to igorts-git/maxtext
that referenced
this pull request
Oct 30, 2026
- MetricsRecorder keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - buffer_metrics eagerly validates metric types and shapes host-side without dispatching device operations, preventing malformed metrics from entering pending buffers. - record_metrics skips intermediate_outputs and tuple/list aux values. Differences from atwigg/mlperf: - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: MetricsRecorder.restore_buffers, weighted_metric_bounds and the metric_bounds checkpoint metadata, the engine's _restore_metrics_buffer and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - MLPerf's update(self, **kwargs) is not adopted. Co-authored-by: Param Bole <parambole@google.com> Fixes AI-Hypercomputer#6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 71 passed. Covers Python-list buffering, eager host-side type/shape validation, the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, and the single-stack flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files).
igorts-git
force-pushed
the
port/pr1-metrics-checkpointing
branch
from
October 30, 2026 17:09
db6c0a4 to
ae6ee1a
Compare
igorts-git
added a commit
to igorts-git/maxtext
that referenced
this pull request
Oct 30, 2026
- MetricsRecorder keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - buffer_metrics eagerly validates metric types and shapes host-side without dispatching device operations, preventing malformed metrics from entering pending buffers. - record_metrics skips intermediate_outputs and tuple/list aux values. - Adds documentation rule in AGENTS.md requiring comments and docstrings to explain current code state from first principles rather than comparing against deleted or legacy implementations. Differences from atwigg/mlperf: - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: MetricsRecorder.restore_buffers, weighted_metric_bounds and the metric_bounds checkpoint metadata, the engine's _restore_metrics_buffer and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - MLPerf's update(self, **kwargs) is not adopted. Co-authored-by: Param Bole <parambole@google.com> Fixes AI-Hypercomputer#6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 71 passed. Covers Python-list buffering, eager host-side type/shape validation, the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, and the single-stack flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files).
igorts-git
force-pushed
the
port/pr1-metrics-checkpointing
branch
from
October 30, 2026 17:25
ae6ee1a to
a092171
Compare
- MetricsRecorder keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - buffer_metrics eagerly validates metric types and shapes host-side without dispatching device operations, preventing malformed metrics from entering pending buffers. - record_metrics skips intermediate_outputs and tuple/list aux values. - Adds documentation rule in AGENTS.md requiring comments and docstrings to explain current code state from first principles rather than comparing against deleted or legacy implementations. Differences from atwigg/mlperf: - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: MetricsRecorder.restore_buffers, weighted_metric_bounds and the metric_bounds checkpoint metadata, the engine's _restore_metrics_buffer and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - MLPerf's update(self, **kwargs) is not adopted. - Added _validate_metric to eagerly validate metric types and shapes host-side in MetricsRecorder.buffer_metrics, rather than deferring failures to flush time. Co-authored-by: Param Bole <parambole@google.com> Fixes AI-Hypercomputer#6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 71 passed. Covers Python-list buffering, eager host-side type/shape validation, the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, and the single-stack flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files).
copybara-service Bot
pushed a commit
that referenced
this pull request
Oct 30, 2026
Imported from GitHub PR #6017 # Description Changes the training engine's `MetricsRecorder` from appending to JAX arrays on every micro-batch to buffering metrics in host-side Python lists and building the arrays once per step, at flush. Why: the eager `jnp.append` path dispatched one device op per metric per micro-batch (about 100 metrics for GRPO). The new flush is one `jnp.stack` per metric per step, independent of the micro-batch count. Changes: - `MetricsRecorder` keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - `buffer_metrics` eagerly validates metric types and shapes host-side without dispatching device operations, preventing malformed metrics from entering pending buffers. - `record_metrics` skips `intermediate_outputs` and tuple/list aux values. - Adds documentation rule in `AGENTS.md` requiring comments and docstrings to explain current code state from first principles rather than comparing against deleted or legacy implementations. ## Differences from `atwigg/mlperf` - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: `MetricsRecorder.restore_buffers`, `weighted_metric_bounds` and the `metric_bounds` checkpoint metadata, the engine's `_restore_metrics_buffer` and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - MLPerf's `update(self, **kwargs)` is not adopted. ## Attribution Ported from Param Bole's #5568 on `atwigg/mlperf`. Co-authored-by: Param Bole <parambole@google.com> Fixes #6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 71 passed. Covers Python-list buffering, eager host-side type/shape validation, the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, and the single-stack flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files). PiperOrigin-RevId: 1009954644
igorts-git
force-pushed
the
port/pr1-metrics-checkpointing
branch
from
October 30, 2026 17:29
a092171 to
99673a5
Compare
copybara-service Bot
pushed a commit
that referenced
this pull request
Oct 30, 2026
Imported from GitHub PR #6017 # Description Changes the training engine's `MetricsRecorder` from appending to JAX arrays on every micro-batch to buffering metrics in host-side Python lists and building the arrays once per step, at flush. Why: the eager `jnp.append` path dispatched one device op per metric per micro-batch (about 100 metrics for GRPO). The new flush is one `jnp.stack` per metric per step, independent of the micro-batch count. Changes: - `MetricsRecorder` keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - `buffer_metrics` eagerly validates metric types and shapes host-side without dispatching device operations, preventing malformed metrics from entering pending buffers. - `record_metrics` skips `intermediate_outputs` and tuple/list aux values. - Adds documentation rule in `AGENTS.md` requiring comments and docstrings to explain current code state from first principles rather than comparing against deleted or legacy implementations. ## Differences from `atwigg/mlperf` - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: `MetricsRecorder.restore_buffers`, `weighted_metric_bounds` and the `metric_bounds` checkpoint metadata, the engine's `_restore_metrics_buffer` and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - MLPerf's `update(self, **kwargs)` is not adopted. - Added `_validate_metric` to eagerly validate metric types and shapes host-side in `MetricsRecorder.buffer_metrics`, rather than deferring failures to flush time. ## Attribution Ported from Param Bole's #5568 on `atwigg/mlperf`. Co-authored-by: Param Bole <parambole@google.com> Fixes #6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 71 passed. Covers Python-list buffering, eager host-side type/shape validation, the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, and the single-stack flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files). PiperOrigin-RevId: 1009954644
4 tasks done
copybara-service Bot
pushed a commit
that referenced
this pull request
Oct 30, 2026
Imported from GitHub PR #6017 # Description Changes the training engine's `MetricsRecorder` from appending to JAX arrays on every micro-batch to buffering metrics in host-side Python lists and building the arrays once per step, at flush. Why: the eager `jnp.append` path dispatched one device op per metric per micro-batch (about 100 metrics for GRPO). The new flush is one `jnp.stack` per metric per step, independent of the micro-batch count. Changes: - `MetricsRecorder` keeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup. - `buffer_metrics` eagerly validates metric types and shapes host-side without dispatching device operations, preventing malformed metrics from entering pending buffers. - `record_metrics` skips `intermediate_outputs` and tuple/list aux values. - Adds documentation rule in `AGENTS.md` requiring comments and docstrings to explain current code state from first principles rather than comparing against deleted or legacy implementations. ## Differences from `atwigg/mlperf` - Checkpoints are taken only between steps (PR 0), so the metrics are never checkpointed: `MetricsRecorder.restore_buffers`, `weighted_metric_bounds` and the `metric_bounds` checkpoint metadata, the engine's `_restore_metrics_buffer` and the intra-step loss-cache rebuild are not ported, nor are the tests for them. - MLPerf's `update(self, **kwargs)` is not adopted. - Added `_validate_metric` to eagerly validate metric types and shapes host-side in `MetricsRecorder.buffer_metrics`, rather than deferring failures to flush time. ## Attribution Ported from Param Bole's #5568 on `atwigg/mlperf`. Co-authored-by: Param Bole <parambole@google.com> Fixes #6017 # Tests ```bash cd tests/post_training/unit python -m pytest maxtext_engine_test.py -q ``` Result: 71 passed. Covers Python-list buffering, eager host-side type/shape validation, the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, and the single-stack flush. Pre-commit (codespell, pylint, pyink) passed. # Checklist Before submitting this PR, please make sure (put X in square brackets): - [x] I have performed a self-review of my code. For an optional AI review, add the `gemini-review` label. - [x] I have necessary comments in my code, particularly in hard-to-understand areas. - [x] I have run end-to-end tests and provided workload links above if applicable. - [x] I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in [our documentation](https://maxtext.readthedocs.io/en/latest/development.html#adding-new-documentation-files). PiperOrigin-RevId: 1009954644
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.
Description
Changes the training engine's
MetricsRecorderfrom appending to JAX arrays on every micro-batch to buffering metrics in host-side Python lists and building the arrays once per step, at flush.Why: the eager
jnp.appendpath dispatched one device op per metric per micro-batch (about 100 metrics for GRPO). The new flush is onejnp.stackper metric per step, independent of the micro-batch count.Changes:
MetricsRecorderkeeps each step's metrics in Python lists and materializes them into 1D arrays once, at flush. The flush is all-or-nothing, and pending items are keyed by buffer identity and dropped on eviction and cleanup.buffer_metricseagerly validates metric types and shapes host-side without dispatching device operations, preventing malformed metrics from entering pending buffers.record_metricsskipsintermediate_outputsand tuple/list aux values.AGENTS.mdrequiring comments and docstrings to explain current code state from first principles rather than comparing against deleted or legacy implementations.Differences from
atwigg/mlperfMetricsRecorder.restore_buffers,weighted_metric_boundsand themetric_boundscheckpoint metadata, the engine's_restore_metrics_bufferand the intra-step loss-cache rebuild are not ported, nor are the tests for them.update(self, **kwargs)is not adopted._validate_metricto eagerly validate metric types and shapes host-side inMetricsRecorder.buffer_metrics, rather than deferring failures to flush time.Attribution
Ported from Param Bole's #5568 on
atwigg/mlperf.Co-authored-by: Param Bole parambole@google.com
Fixes #6017
Tests
cd tests/post_training/unit python -m pytest maxtext_engine_test.py -qResult: 71 passed. Covers Python-list buffering, eager host-side type/shape validation, the flush layout (including more micro-batches after a mid-step flush), same-id buffers kept apart, all-or-nothing flush, eviction and cleanup of pending items, and the single-stack flush. Pre-commit (codespell, pylint, pyink) passed.
Checklist
Before submitting this PR, please make sure (put X in square brackets):
gemini-reviewlabel.