Skip to content

feat(refit): add RL trainer client and Megatron adapter - #616

Merged
zhengluo-nv merged 1 commit into
mainfrom
zheluo/refit-megatron-adapter
Aug 14, 2026
Merged

feat(refit): add RL trainer client and Megatron adapter#616
zhengluo-nv merged 1 commit into
mainfrom
zheluo/refit-megatron-adapter

Conversation

@zhengluo-nv

@zhengluo-nv zhengluo-nv commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add the synchronous, rank-local ModelExpressTrainerClient lifecycle for staging and publishing versioned trainer shards
  • add a framework-neutral TrainerEngineAdapter contract and rank-local manifest service
  • add the first Megatron trainer adapter by reusing the existing NIXL registration and reshard manifest implementation
  • organize Megatron implementations under canonical modelexpress_rl/train/... and modelexpress_rl/inference/... namespaces

Why

The Redis-backed RefitService provides the version and shard control plane, but RL trainer actors still need a framework-facing client that connects their native engine tensors to those APIs. This PR adds that client boundary without wiring ModelExpress into a specific RL framework.

The intended lifecycle is:

  1. The RL orchestrator creates a global WeightVersion.
  2. Each trainer rank stages its local contribution through its engine adapter.
  3. Each rank publishes its WeightVersionShard metadata and serves its immutable manifest.
  4. The server marks the version READY after all expected source slots are published.
  5. A future version-retirement integration will complete source_reuse_ready; until then the Megatron IN_PLACE implementation fails that fence explicitly instead of claiming the source buffers are reusable.

API and implementation notes

  • ModelExpressTrainerClient.initialize() resolves RL deployment policy from modelexpress_rl.envs and shared connectivity settings from modelexpress.envs, constructs the selected trainer adapter internally, and maintains worker registration.
  • RL-specific environment configuration is limited to trainer engine, staging mode, and payload format; model/server/worker/heartbeat settings continue to use the shared ModelExpress environment module.
  • the engine passes its live NIXL manager and manifest publisher but does not construct or supply a TrainerEngineAdapter.
  • the Megatron manager dependency is typed by the narrow agent_name, nixl_metadata, and metadata-listener port protocol used by publication.
  • the client has a simple no-argument constructor; initialize() remains the supported setup path.
  • worker_endpoint identifies the trainer-side manifest service, while server_url identifies the central ModelExpress control plane.
  • stage_shard() delegates engine-specific tensor discovery and staging to TrainerEngineAdapter.
  • StagedWeightVersionShard.publish() is idempotent and publishes only control metadata; weight bytes remain on trainer-owned buffers.
  • all staged buffer owners for a version remain retained; publishing another shard for the same version does not release an earlier allocation.
  • MegatronTrainerAdapter currently supports IN_PLACE plus FULL_TENSOR; it derives the source slot from the initialized Megatron global rank and the NIXL metadata endpoint from the shared worker host plus the manager's listen port.
  • Canonical Megatron-specific APIs live under modelexpress_rl; temporary re-exports at the prior modelexpress.refit.reshard paths preserve NeMo-RL #3632 compatibility while the shared reshard core remains engine-neutral.

Validation

  • 200 passed across the environment, trainer-client, Megatron, and refit/reshard Python suite on the rebased, single-commit head
  • 4 passed against a real Redis 7 backend in the RefitService gRPC lifecycle suite, covering automatic readiness, replacement publishers, leases, release, shard deletion, and worker expiry
  • a live cross-language E2E ran the Python ModelExpressTrainerClient and Megatron adapter against the Rust ModelExpress server and Redis backend: the trainer registered, published its shard, served its manifest through RefitWorkerService, and advanced the version from STAGING to READY
  • the same E2E exercised a generator-like consumer that discovered the published shard, fetched the worker-local manifest, verified its SHA-256 digest and tensor metadata, registered and deleted a version lease, released the version to RELEASING, and deleted the source shard
  • the E2E used synthetic registered tensor addresses and NIXL metadata; it validates the API and metadata lifecycle but does not claim a real GPU/NIXL byte transfer
  • Python CI with protobuf 5 and protobuf 6, amd64 and arm64 client wheel builds, and the server image build passed on the prior head; those checks have restarted for this amended head
  • Ruff passes for the changed source and test files, the generated gRPC stubs pass the reported F541 check, and git diff --check origin/main...HEAD passes

Not included

  • direct NeMo-RL or another RL framework call-site wiring
  • generator-side planning, transfer, or weight installation
  • Megatron version-retirement signaling for IN_PLACE buffer reuse
  • a real GPU/NIXL data-transfer qualification; this PR reuses the existing registered-buffer and manifest path

Summary by CodeRabbit

  • New Features
    • Added RL trainer support for registering workers, staging and publishing weight shards, renewing leases, and retrieving manifests.
    • Added Megatron training and inference resharding support with validation, shard layouts, aliases, and publication helpers.
    • Added configuration options for trainer engines, staging modes, payload formats, source slots, and metadata endpoints.
    • Added manifest retrieval through the refit service.
  • Documentation
    • Expanded setup guidance for trainer weight-version publication and Megatron integration.
  • Refactor
    • Consolidated Megatron resharding APIs while retaining compatibility aliases.
  • Tests
    • Added coverage for trainer publication, manifest retrieval, validation, and environment settings.

@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:15 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:15 Active
@github-actions github-actions Bot added the feat label Aug 12, 2026
@zhengluo-nv zhengluo-nv self-assigned this Aug 12, 2026
@zhengluo-nv
zhengluo-nv marked this pull request as ready for review August 12, 2026 21:34
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: bd41fdeb-fc72-4a05-968d-2892cf5fea7a

📥 Commits

Reviewing files that changed from the base of the PR and between b1e373d and c0fc5f0.

📒 Files selected for processing (20)
  • modelexpress_client/python/README.md
  • modelexpress_client/python/generate_proto.sh
  • modelexpress_client/python/modelexpress/envs.py
  • modelexpress_client/python/modelexpress/p2p_pb2_grpc.py
  • modelexpress_client/python/modelexpress/refit/reshard/__init__.py
  • modelexpress_client/python/modelexpress/refit/reshard/megatron_publisher.py
  • modelexpress_client/python/modelexpress_rl/client.py
  • modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/layout.py
  • modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/receiver.py
  • modelexpress_client/python/modelexpress_rl/refit_pb2_grpc.py
  • modelexpress_client/python/modelexpress_rl/train/__init__.py
  • modelexpress_client/python/modelexpress_rl/train/adapter.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/__init__.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/adapter.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/aliases.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/publisher.py
  • modelexpress_client/python/tests/test_envs.py
  • modelexpress_client/python/tests/test_refit_megatron_adapter.py
  • modelexpress_client/python/tests/test_refit_trainer_client.py
  • modelexpress_client/python/tests/test_reshard_megatron.py
💤 Files with no reviewable changes (2)
  • modelexpress_client/python/modelexpress/refit/reshard/megatron_publisher.py
  • modelexpress_client/python/modelexpress/refit/reshard/init.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • modelexpress_client/python/modelexpress_rl/train/init.py
  • modelexpress_client/python/README.md
  • modelexpress_client/python/tests/test_refit_megatron_adapter.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/aliases.py
  • modelexpress_client/python/modelexpress_rl/refit_pb2_grpc.py
  • modelexpress_client/python/tests/test_refit_trainer_client.py
  • modelexpress_client/python/modelexpress_rl/client.py

Walkthrough

The change adds RL trainer refit APIs, protobuf and gRPC bindings, manifest publication and retrieval, Megatron training and inference support, environment configuration, compatibility exports, documentation, and tests.

Changes

RL refit protocol

Layer / File(s) Summary
Refit protocol and generated bindings
modelexpress_common/proto/refit.proto, modelexpress_client/python/generate_proto.sh, modelexpress_client/python/modelexpress_rl/refit_pb2*.py
Adds worker manifest retrieval to the protobuf contract and generates bindings for both refit and P2P APIs.

Trainer publication flow

Layer / File(s) Summary
Trainer contracts, client, and manifest service
modelexpress_client/python/modelexpress_rl/{client.py,train/*}, modelexpress_client/python/modelexpress_rl/train/manifest.py, modelexpress_client/python/modelex/envs.py
Adds staging contracts, completion fences, manifest types, worker registration renewal, shard publication, retained buffers, environment settings, and manifest retrieval.

Megatron support

Layer / File(s) Summary
Megatron staging, aliasing, and compatibility
modelexpress_client/python/modelexpress_rl/train/engines/megatron/*, modelexpress_client/python/modelex/refit/reshard/__init__.py
Adds in-place full-tensor staging, tensor alias validation, rendezvous manifest publication, and updated compatibility exports.
Megatron inference target lowering
modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/*
Adds validated target specifications, TP layout lowering, shard-axis resolution, and receiver wiring.

Validation and documentation

Layer / File(s) Summary
Integration coverage and usage documentation
modelexpress_client/python/tests/test_refit_*.py, modelexpress_client/python/tests/test_reshard_megatron.py, modelex_client/python/tests/test_envs.py, modelexpress_client/python/README.md
Adds end-to-end publication tests, validation coverage, environment tests, and trainer publication documentation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Mergeability Score: 🟠 High · up to c0fc5

The PR adds rank-local trainer staging and publishing, but the Megatron IN_PLACE path can still leave a trainer rank waiting indefinitely, while the new package layout can make imports fail depending on order; malformed tensor geometry is also accepted. These issues can cause hangs or runtime failures, so the PR is not merge-ready until the liveness and import risks are fixed or explicitly accepted.

Poem

I’m a rabbit watching shards take flight,
Through fences, manifests, clean and bright.
Megatron hops with tensors in line,
While gRPC carries each design.
The trainer publishes, tests approve—
And every little buffer can move.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: adding an RL trainer client and a Megatron adapter for refit workflows.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
modelexpress_client/python/modelexpress_rl/train/engines/megatron/aliases.py (2)

164-173: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Report missing QKV extras with the tensor name.

Lines 166 to 168 index item.extras directly. A missing key raises KeyError('head_dim') without the tensor name. Every other validation in this module raises ValueError prefixed with item.name. Align this path so a publisher misconfiguration identifies the offending tensor.

♻️ Proposed change
-    head_dim = int(item.extras["head_dim"])
-    q_heads_local = int(item.extras["num_heads_local"])
-    kv_heads_local = int(item.extras["num_kv_heads_local"])
+    required = ("head_dim", "num_heads_local", "num_kv_heads_local")
+    missing = [key for key in required if key not in item.extras]
+    if missing:
+        raise ValueError(f"{item.name}: QKV aliasing requires extras {missing}")
+    head_dim = int(item.extras["head_dim"])
+    q_heads_local = int(item.extras["num_heads_local"])
+    kv_heads_local = int(item.extras["num_kv_heads_local"])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modelexpress_client/python/modelexpress_rl/train/engines/megatron/aliases.py`
around lines 164 - 173, Update the QKV validation path around item.extras access
to catch missing head_dim, num_heads_local, or num_kv_heads_local metadata and
raise a ValueError prefixed with item.name, preserving the existing validation
behavior for present extras.

142-147: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Cross-check the derived gated full_shape against item.global_shape.

_build_gated_aliases derives full_shape from the local tensor shape and the source group size. It never compares the result with the declared item.global_shape. The non-fused axes therefore come from local geometry only, and a caller that declares an inconsistent global_shape gets no error. The single-name path at line 255 uses item.global_shape directly, so the two paths trust different sources of truth.

Add an assertion that the derived fused extent agrees with item.global_shape[axis] // 2 and that the remaining dimensions match.

♻️ Proposed validation
     source_rank, source_size = _source_rank_and_size(item, axis)
     full_shape = list(item.tensor.shape)
     full_shape[axis] = half * source_size
+    expected = list(int(dim) for dim in item.global_shape)
+    expected[axis] //= 2
+    if expected != [int(dim) for dim in full_shape]:
+        raise ValueError(
+            f"{item.name}: derived gate/up shape {tuple(full_shape)} disagrees "
+            f"with declared global shape {item.global_shape}"
+        )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modelexpress_client/python/modelexpress_rl/train/engines/megatron/aliases.py`
around lines 142 - 147, Update _build_gated_aliases after deriving full_shape to
validate it against item.global_shape: require the fused axis extent to equal
item.global_shape[axis] // 2 and all non-fused dimensions to match exactly.
Raise an assertion or equivalent validation error before constructing
shard_range when the declared global shape is inconsistent.
modelexpress_client/python/tests/test_refit_trainer_client.py (1)

96-96: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Replace the fixed sleep with a bounded poll to avoid a flaky renewal assertion.

Line 96 sleeps 0.4 s and line 130 asserts service.registration_count >= 2. That couples the test to the renewal interval derived from registration_ttl_seconds=1. If the renewal interval is at or above 0.4 s, or if the CI machine is loaded, the second registration does not arrive and the test fails. Poll until the count reaches 2 with a generous deadline.

♻️ Proposed change
-        time.sleep(0.4)
+        deadline = time.monotonic() + 10.0
+        while service.registration_count < 2 and time.monotonic() < deadline:
+            time.sleep(0.02)
+        assert service.registration_count >= 2

Then drop the assertion at line 130.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modelexpress_client/python/tests/test_refit_trainer_client.py` at line 96,
Replace the fixed time.sleep(0.4) in the renewal test with a bounded polling
loop that waits until service.registration_count reaches 2, using a generous
deadline and short polling interval. Preserve timeout protection, then remove
the separate registration_count >= 2 assertion because the poll should enforce
the condition.
modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/receiver.py (1)

5-7: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

The two packages now import each other.

This module imports from modelexpress. At the same time modelexpress_client/python/modelexpress/refit/reshard/megatron_aliases.py imports from modelexpress_rl. The dependency edges therefore run in both directions between the two top-level packages. That makes the import order significant and it can produce partially initialized modules if either side later imports at package __init__ level.

Pick one direction. Keep the shared implementations in a single owning package and let the other package re-export only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/receiver.py`
around lines 5 - 7, Remove the bidirectional package dependency by choosing one
owning package for Megatron reshard implementations. Update
MegatronReshardReceiver and the related megatron_aliases re-export so only the
non-owning package imports and re-exports from the owning package; ensure no
module under either top-level package imports back in the opposite direction.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@modelexpress_client/python/modelexpress_rl/client.py`:
- Around line 242-245: Update the publication bookkeeping around
self._published_shards and StagedWeightVersionShard.publish() so every
successfully published staging allocation remains retained for the version,
including repeated publications with different buffer_owner objects;
alternatively reject duplicate publications for the same version and source slot
before replacing the existing handle. Preserve the existing lifecycle behavior
that releases retained buffers only during later eviction/release.

In `@modelexpress_client/python/modelexpress_rl/refit_pb2_grpc.py`:
- Line 24: Update the proto generation flow used by generate_proto.sh so both
generated gRPC stubs avoid the redundant f-string prefix causing the F541 lint
error; alternatively configure Ruff to exclude the generated protobuf modules.
Do not modify only refit_pb2_grpc.py or other checked-in generated output, and
ensure regeneration produces lint-clean stubs consistently.

In
`@modelexpress_client/python/modelexpress_rl/train/engines/megatron/adapter.py`:
- Around line 89-99: The source_reuse_ready fence in
MegatronTrainerAdapter.stage_shard must not wait on an unretained, unset Event:
either retain and signal the event during version retirement, or make the fence
callable raise NotImplementedError until that lifecycle exists. In
modelexpress_client/python/modelexpress_rl/train/engines/megatron/adapter.py
lines 89-99, implement the chosen behavior; in
modelexpress_client/python/tests/test_refit_megatron_adapter.py lines 108-131,
add a staged.source_reuse_ready assertion matching that behavior, following the
existing trainer-client fence test pattern.

Apply the same fix in
`@modelexpress_client/python/tests/test_refit_megatron_adapter.py` around lines
108 - 131: The test currently omits the reuse-fence wait, allowing the blocking
defect to pass unnoticed.

---

Nitpick comments:
In
`@modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/receiver.py`:
- Around line 5-7: Remove the bidirectional package dependency by choosing one
owning package for Megatron reshard implementations. Update
MegatronReshardReceiver and the related megatron_aliases re-export so only the
non-owning package imports and re-exports from the owning package; ensure no
module under either top-level package imports back in the opposite direction.

In
`@modelexpress_client/python/modelexpress_rl/train/engines/megatron/aliases.py`:
- Around line 164-173: Update the QKV validation path around item.extras access
to catch missing head_dim, num_heads_local, or num_kv_heads_local metadata and
raise a ValueError prefixed with item.name, preserving the existing validation
behavior for present extras.
- Around line 142-147: Update _build_gated_aliases after deriving full_shape to
validate it against item.global_shape: require the fused axis extent to equal
item.global_shape[axis] // 2 and all non-fused dimensions to match exactly.
Raise an assertion or equivalent validation error before constructing
shard_range when the declared global shape is inconsistent.

In `@modelexpress_client/python/tests/test_refit_trainer_client.py`:
- Line 96: Replace the fixed time.sleep(0.4) in the renewal test with a bounded
polling loop that waits until service.registration_count reaches 2, using a
generous deadline and short polling interval. Preserve timeout protection, then
remove the separate registration_count >= 2 assertion because the poll should
enforce the condition.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c501863d-c0c2-4501-affe-903295b080bf

📥 Commits

Reviewing files that changed from the base of the PR and between 5cfbd34 and b1e373d.

📒 Files selected for processing (25)
  • modelexpress_client/python/README.md
  • modelexpress_client/python/generate_proto.sh
  • modelexpress_client/python/modelexpress/refit/reshard/megatron_aliases.py
  • modelexpress_client/python/modelexpress/refit/reshard/megatron_publisher.py
  • modelexpress_client/python/modelexpress_rl/__init__.py
  • modelexpress_client/python/modelexpress_rl/client.py
  • modelexpress_client/python/modelexpress_rl/inference/__init__.py
  • modelexpress_client/python/modelexpress_rl/inference/reshard/__init__.py
  • modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/__init__.py
  • modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/layout.py
  • modelexpress_client/python/modelexpress_rl/inference/reshard/megatron/receiver.py
  • modelexpress_client/python/modelexpress_rl/refit_pb2.py
  • modelexpress_client/python/modelexpress_rl/refit_pb2_grpc.py
  • modelexpress_client/python/modelexpress_rl/train/__init__.py
  • modelexpress_client/python/modelexpress_rl/train/adapter.py
  • modelexpress_client/python/modelexpress_rl/train/engines/__init__.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/__init__.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/adapter.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/aliases.py
  • modelexpress_client/python/modelexpress_rl/train/engines/megatron/publisher.py
  • modelexpress_client/python/modelexpress_rl/train/manifest.py
  • modelexpress_client/python/tests/test_refit_megatron_adapter.py
  • modelexpress_client/python/tests/test_refit_trainer_client.py
  • modelexpress_client/python/tests/test_reshard_megatron.py
  • modelexpress_common/proto/refit.proto

Comment thread modelexpress_client/python/modelexpress_rl/client.py Outdated
Comment thread modelexpress_client/python/modelexpress_rl/refit_pb2_grpc.py Outdated
Comment thread modelexpress_client/python/modelexpress_rl/train/engines/megatron/adapter.py Outdated
@zhengluo-nv
zhengluo-nv force-pushed the zheluo/refit-megatron-adapter branch from b1e373d to 23c64e4 Compare August 12, 2026 21:42
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:42 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:42 Active
@zhengluo-nv
zhengluo-nv marked this pull request as draft August 12, 2026 21:43
@zhengluo-nv
zhengluo-nv force-pushed the zheluo/refit-megatron-adapter branch from 23c64e4 to dd3f97a Compare August 12, 2026 21:46
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:46 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:46 Active
@zhengluo-nv
zhengluo-nv force-pushed the zheluo/refit-megatron-adapter branch from dd3f97a to cfaab7a Compare August 12, 2026 21:54
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:54 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 21:54 Active
@zhengluo-nv
zhengluo-nv force-pushed the zheluo/refit-megatron-adapter branch from cfaab7a to a1e3a1a Compare August 12, 2026 21:59
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 22:00 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 22:00 Active
@zhengluo-nv
zhengluo-nv force-pushed the zheluo/refit-megatron-adapter branch from a1e3a1a to 949fe25 Compare August 12, 2026 22:03
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 12, 2026 22:03 Active
@zhengluo-nv
zhengluo-nv force-pushed the zheluo/refit-megatron-adapter branch from 8893dd1 to c1d4f31 Compare August 13, 2026 16:48
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 13, 2026 16:48 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 13, 2026 16:48 Active
@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 13, 2026 23:09 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 13, 2026 23:09 Active
@KavinKrishnan

Copy link
Copy Markdown
Contributor

Overall, this is a strong refactor. Separating the version lifecycle in ModelExpressTrainerClient from engine-specific staging in TrainerEngineAdapter gives NeMo-RL and other frameworks a much cleaner integration point.

Copy link
Copy Markdown
Contributor Author

Review follow-up: commit 8f9437d8 also addresses CodeRabbit's finding that failed to post inline. MegatronTargetSpec and MegatronTargetLayout now reject booleans and non-integral global_shape, tp_size, and tp_rank values before partitioning. Regression coverage is included; the final environment/trainer/Megatron/refit/reshard suite passes (200 passed), along with Ruff and git diff --check.

Comment thread modelexpress_client/python/modelexpress_rl/train/adapter.py
Signed-off-by: Zheng Luo <zheluo@nvidia.com>
@zhengluo-nv
zhengluo-nv force-pushed the zheluo/refit-megatron-adapter branch from 8f9437d to 3bcc6ba Compare August 14, 2026 18:53
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 14, 2026 18:53 Active
@copy-pr-bot
copy-pr-bot Bot deployed to automated-release August 14, 2026 18:53 Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants