Skip to content

Tinker seam re-port: decoupled fb/step on current upstream (supersedes fork main) - #2

Merged
GavinZhu-GMI merged 6 commits into
mainfrom
tinker-seam
Jul 14, 2026
Merged

GavinZhu-GMI merged 6 commits into
mainfrom
tinker-seam

Conversation

@GavinZhu-GMI

@GavinZhu-GMI GavinZhu-GMI commented Jul 14, 2026 •

Copy link
Copy Markdown
Owner

Re-ports the Tinker orchestration interface onto current upstream radixark/miles (fecd5d9), replacing the old fork implementation (main is 63 ahead / 648 behind upstream). Merging fast-forwards this fork to upstream + a minimal seam.

The real review surface is the seam vs upstream: 6 commits, +392/−71 over 9 files (compare vs fecd5d9) — everything else in this PR's diff is upstream catching up.

The seam

  • forward_backward_pass / optimizer_step split out of train_one_step (megatron_utils/model.py) — fwd/bwd with no optimizer step and no zero_grad, then a decoupled step with per-call learning_rate returning {success, grad_norm}.
  • Grad accumulation across fb calls: forward_backward_pass swaps config.finalize_model_grads_func to a no-op (restored in finally); optimizer_step runs finalize_model_grads_with_empty_cache once before optimizer.step() — mirroring Megatron's own microbatch accumulation. Also saves one DP reduce per fb call.
  • Pure-sum loss semantics via _loss_norm_total=1 batch key — gradient is split-invariant across any fb pipelining depth; normalization stays in client weights per the Tinker contract.
  • _loss_type_override per-request loss selection; _partition_indices for client-order per-sample outputs; fb returns per-sample response log-probs (computed on pre-step weights).
  • TinkerTrainGroup async Ray fanout (miles/ray/tinker_group.py); DP-split passthrough for client-supplied advantages/log_probs; MILES_REPO docker build arg.

Validation (ns.config 4×H200, DP=4, Qwen2.5-0.5B bridge-LoRA, 2026-07-13/14)

  • Grad accumulation parity: grad_norm bit-identical for 1×fb(8) vs 2×fb(4) + step (ratio exactly 1.0). This also verifies 0e89c58 (marked UNVERIFIED in its commit message at push time): before the deferred finalization, the per-fb-call reduce-scatter corrupted the grad buffer as an accumulation substrate (ratio 0.698 on bridge-LoRA).
  • Client-order outputs: exact through DP=4 with distinct-length markers.
  • Real recipe: tinker-cookbook sl_basic (NoRobots SFT, 30 steps) end-to-end via TinkerCloud, NLL 2.74 → 2.34, checkpoints saved.

Companion PR (backend adaptation): GMISWE/tinker-cloud#15.

Follow-up candidates: upstream the seam to radixark/miles; extend loss_hub if recipes need per-sample logprobs beyond the response slice; load_checkpoint(path) full-resume on the actor.

GavinZhu-GMI added a commit that referenced this pull request Jul 14, 2026
…am tree

The old fork implementation of the Tinker Ray interface (main, cd8e75a) is
fully superseded by this branch's re-port onto upstream fecd5d9; the 'ours'
strategy keeps the seam tree unchanged. See PR #2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
GavinZhu-GMI and others added 6 commits July 14, 2026 01:20
…er step)

Tinker's API pipelines N forward_backward calls then one optim_step; upstream
couples fwd+bwd+step inside train_one_step. This adds the minimal seam
(specs/005 design in tinker-nemorl), reusing upstream data/loss/fanout:

- model.py: extract _build_train_forward_step + _configure_train_step from
  train_one_step/train (pure moves); add forward_backward_pass (no step,
  grads accumulate across calls) and optimizer_step (per-call LR override;
  when the client sets LR the Megatron scheduler is not stepped).
- loss: per-batch _loss_type_override (per-request loss selection) and
  _loss_norm_total (=1 -> pure-sum gradients, invariant to how a batch is
  split across forward_backward calls; fixes the 2x grad inflation measured
  in the G1 spike). Same rollout-key pattern as dynamic_global_batch_size.
- data: forward the two scalar keys in get_batch; keep _partition_indices in
  process_rollout_data so per-sample outputs reassemble into client order.
- actor: forward_backward_only / apply_optimizer_step / forward_logprobs /
  load_checkpoint (full resume incl. optimizer+scheduler).
- ray/tinker_group.py (new): TinkerTrainGroup(RayTrainGroup) async fanout +
  DP-order merge. Frozen v1 RayTrainGroup untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tinker clients send advantages/log_probs/returns/values per sample (no
actor-side compute_advantages_and_returns), and the seam's scalar keys
(_loss_type_override, _loss_norm_total) must reach every rank. Add them to
split_train_data_by_dp_raw's whitelists; absent keys are skipped, so
non-Tinker paths are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tinker's fb contract includes per-datum logprobs (the SDK weights its
chunk reduction by len(loss_fn_outputs) and the cookbook computes NLL
from them). Computed via a forward-only pass on the same pre-step
weights; extracting them from the loss pass itself is a follow-up
optimization.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fixes multi-fb grad accumulation on bridge-LoRA (G1 ratio 0.698 ~ 1/sqrt(2)).
Probe evidence: fb2-entry buffer norms exactly equal fb1-exit (nothing
zeroes), but fb2-exit barely moves / can DECREASE (219.23->219.35;
199.85->173.85) instead of matching the fresh fb(8) norms — the per-fb
finalize (reduce-scatter) rewrites local grads with reduced shards, so the
next backward accumulates onto corrupted contents. The raw full-FT path
survived only by ddp_config luck (exact 1.0).

Fix mirrors megatron's own microbatch accumulation: fb passes run with a
no-op finalize_model_grads_func (restored after), and optimizer_step calls
finalize_model_grads once over the locally-accumulated buffers before
optimizer.step().

Runtime-verified 2026-07-14 (ns.config 4xH200, DP=4, Qwen2.5-0.5B
bridge-LoRA): accumulation probe grad_norm bit-identical for 1xfb(8) vs
2xfb(4) + step (ratio exactly 1.0, was 0.698); full G1/G2 gates + sl_basic
recipe rerun green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@GavinZhu-GMI
GavinZhu-GMI merged commit df3f75c into main Jul 14, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant