fix(training): select XLAStrategy for multi-device XLA/TPU training - #1427
Merged
Borda merged 3 commits intoSep 4, 2026
Merged
Conversation
JESUSROYETH
requested review from
Borda,
SkalskiP,
isaacrob and
probicheaux
as code owners
September 4, 2026 11:56
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1427 +/- ##
=======================================
Coverage 86% 86%
=======================================
Files 114 114
Lines 15052 15062 +10
=======================================
+ Hits 13006 13016 +10
Misses 2046 2046 🚀 New features to boost your workflow:
|
JESUSROYETH
force-pushed
the
fix/xla-multi-device-strategy
branch
from
September 4, 2026 14:35
079f17c to
b3a9049
Compare
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The source comments, tests, and changelog incorrectly attribute RF-DETR’s DDP selection to Lightning.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Fixes multi-device and multi-node XLA trainer configuration by selecting a compatible strategy.
Changes:
- Detects explicit and auto-resolved XLA accelerators.
- Selects
XLAStrategyfor distributed non-keypoint training. - Adds strategy tests and release notes.
File summaries
| File | Description |
|---|---|
src/rfdetr/training/trainer.py |
Adds XLA detection and strategy selection. |
tests/training/test_build_trainer.py |
Tests XLA resolution and dispatch scenarios. |
CHANGELOG.md |
Documents the training fix. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Changes: - Restrict automatic XLA strategy promotion to multiple local devices and document that one-device-per-host XLA remains unvalidated. - Correct the DDP root-cause documentation and extend auto-XLA coverage to assert its precision-plugin contract. Impact: - Prevents the trainer from claiming an unsupported one-device multi-node XLA topology while preserving supported multi-device XLA routing. - Keeps release notes and regression tests aligned with RF-DETR's actual DDP control flow. Verification: - `pre-commit run --all-files` passed. - Focused XLA trainer suite: 10 passed, 4 hardware-dependent skips. Residual limits: - No real TPU or multi-host XLA execution was run. - GitHub review threads and portable review-artifact promotion require external authorized environments. --- Co-authored-by: Codex <codex@openai.com>
Borda
approved these changes
Sep 4, 2026
Borda
added a commit
that referenced
this pull request
Sep 7, 2026
…1427) * select XLAStrategy for multi-device XLA/TPU training * restrict XLA promotion to local multi-device runs --------- Co-authored-by: Jesús Royeth <JESUSROYETH@users.noreply.github.com> Co-authored-by: Jirka Borovec <6035284+Borda@users.noreply.github.com> Co-authored-by: Codex <codex@openai.com>
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.
Summary
Asking for more than one TPU chip fails before any accelerator work happens:
XLAAcceleratorpairs only withSingleDeviceXLAStrategyorXLAStrategy. Butbuild_trainer's own strategy branch turnsstrategy="auto"intoDDPStrategy(find_unused_parameters=True)as soon as more than one device is requested:TrainConfig.devicesdefaults to1, a default TPU run never reaches that branch and works fine. But if you ask for the whole slice, the run dies duringTrainerconstruction. Since it fails before touching a chip, it looks like a configuration mistake and not a missing feature, and the one-word workaround (strategy="xla") is nowhere in the error message.This change selects
"xla"when the accelerator resolves to XLA/TPU, the strategy is still"auto", and more than one device or node is requested. It's the same kind of gapprecisionalready needed handling for on this path: XLA needs its own object, the generic default doesn't work.Two more paths hit the same crash and need the same fix:
accelerator="auto", which isTrainConfig.accelerator's own default.build_trainerdecides the strategy beforeTrainerruns its own accelerator resolution, so checking only for the literal strings"xla"/"tpu"misses the case where the caller never names an accelerator at all — this is the documented default on purpose (TrainConfig.accelerator's own docstring: "device is intentionally absent: PTL auto-detects accelerator viaTrainer(accelerator="auto")").xla_acceleratoris now computed by a helper,_accelerator_resolves_to_xla, that also checksXLAAccelerator.is_available()for"auto"— it follows the same priority order (XLAAcceleratorchecked first) thatlightning_fabric.utilities.device_parser._select_auto_acceleratoruses.num_nodes > 1with a single device per host (a multi-host XLA topology). The guard's own multi-device check,_requests_multiple_devices(devices, accelerator), only looked atdevices. The pre-existingdistributed_requestedcomputation a few lines below already treatsnum_nodes > 1as distributed too, so now the guard checks the same condition.Scope
"auto"never reaches the DDP branch there, so it still resolves toSingleDeviceXLAStrategy. The precision-plugin branch (XLAPrecisionvs. a rawprecision=string) now also activates foraccelerator="auto"resolving to XLA on a single device, because it reads the samexla_acceleratorvalue as the strategy guard. This was already needed (XLAStrategy/SingleDeviceXLAStrategyreject a raw precision string) and gives the same resolved precision value either way.strategyis never overridden. An explicit"ddp"still resolves to the sameDDPStrategyobject as before — thatstrategy_name == "ddp"branch already existed, is unrelated to this change, and fires the same with or without XLA.xla_accelerator, and_accelerator_resolves_to_xlareturnsFalsefor any accelerator other than"xla"/"tpu"/an XLA-resolving"auto".find_unused_parameters=Truehandling that the DDP branch relies on has no validated XLA equivalent. Souse_grouppose_keypoints=Trueconfigs still hit the pre-existingDDPStrategy/XLAAcceleratormismatch, instead of silently running a combination nobody validated.segmentation_head, so a segmentation config reaches"xla"the same way plain detection does.Validation
TestAcceleratorResolvesToXLAunit-tests_accelerator_resolves_to_xladirectly (mockingXLAAccelerator.is_available, notorch_xlaneeded): explicit"tpu"/"xla"(case-insensitive) are always XLA;"auto"matches whateveris_available()reports;"cpu"/"gpu"are never XLA no matter what. 7/7 passed.TestMultiDeviceXLAStrategycoversbuild_trainer's actual strategy dispatch. The first four cases need realtorch_xla(markedxla,importorskip-guarded) becausebuild_trainerbuilds a realXLAPrecisionon this path. The newer cases patchXLAPrecisioninstead (and, foraccelerator="auto",XLAAccelerator.is_available), the same wayTestBuildTrainerPrecision's existing XLA tests already do, so they run on every CI lane:test_accelerator_auto_resolves_to_xla_strategy_when_xla_is_available(accelerator="auto",devices=4, XLA mocked available)strategy == "xla"test_multi_node_single_device_selects_xla_strategy(accelerator="tpu",devices=1,num_nodes=2)strategy == "xla"test_multi_device_xla_strategy_is_selected_for_segmentation_models(accelerator="tpu",devices=4,segmentation_head=True)strategy == "xla"Reverting only the source fix (the whole
if (...): strategy = "xla"block disabled, tests kept) turns all three into failures —strategystays aDDPStrategyobject instead of"xla". So each test is checking the guard it targets, not passing by accident.On a Cloud TPU v6e-1 (
southamerica-west1-a, runtimev2-alpha-tpuv6e), torch 2.9.1, torch_xla 2.9.0, libtpu 0.0.21, pytorch-lightning 2.6.5, against this base commit, withaccelerator="tpu"passed explicitly:TestMultiDeviceXLAStrategy(pre-existing, real hardware)test_multiple_xla_devices_select_the_xla_strategyassert <DDPStrategy object...>test_single_xla_device_keeps_autotest_an_explicit_strategy_is_never_overriddentest_multi_device_xla_strategy_is_not_selected_for_keypoint_modelsnot has_keypointsclause removed (guard otherwise intact)isinstance(strategy, DDPStrategy)strategyis the string"xla", not aDDPStrategyThat last row is a different mutation on purpose. Removing the entire guard leaves keypoint configs on the pre-existing DDP branch anyway, so that assertion would hold either way and wouldn't tell us anything about the keypoint exclusion specifically. Removing only the
has_keypointscheck isolates it instead. Both mutations ran locally against the CPU-mockedXLAPrecisionpath (_mc(use_grouppose_keypoints=True)etc.) with the same result, then got re-verified with realtorch_xlaon the arm shown above.On a Cloud TPU v6e-4 (4 chips,
xla:0-xla:3), same base commit,accelerator="tpu"anddevices=4passed explicitly (not theaccelerator="auto"default — that path is only covered by the CPU-mocked test above, not yet by real hardware):developunpatchedValueError: The \XLAAccelerator` can only be used with a `SingleDeviceXLAStrategy` or `XLAStrategy`, found DDPStrategy.`strategy=XLAStrategy,accelerator=XLAAccelerator, Lightning reportsTPU available: True, using: 4 TPU coresThe unpatched run prints rf-detr's own line right before it fails, and that's where the
DDPStrategycomes from:test_all_gather_multiprocess_xla_collective_routingalso passes on that slice in 18.11 s, so the four chips are doing real multi-replica work.Training end to end across replicas was measured separately on 2026-08-24, on an earlier
developcommit, on a v5litepod-4, withstrategy="xla"passed explicitly (the pre-existing workaround, not touched by this change — not theaccelerator="auto"auto-detection path this PR adds): the same configuration went from failing in 6.3 s to completing 2 epochs over 468 images in 919.2 s. This PR makes no multi-chip throughput claim — on that small dataset four chips weren't faster than one, since each replica pays its own warm-up.Still not verified on real TPU silicon:
accelerator="auto"resolving to XLA,num_nodes > 1, and a segmentation config reaching the guard. All three are covered by the CPU-mocked tests above, but not by a real multi-chip/multi-host run.Refs #1058.