Feat/multi gpu training - #40
Open
zhiheng-yang wants to merge 7 commits into
Open
zhiheng-yang wants to merge 7 commits into
zhiheng-yang wants to merge 7 commits into
Conversation
zhiheng-yang
force-pushed
the
feat/multi-gpu-training
branch
from
September 14, 2026 00:39
16d2844 to
54e2945
Compare
zhiheng-yang
marked this pull request as ready for review
September 14, 2026 11:12
zhiheng-yang
marked this pull request as draft
September 14, 2026 11:12
zhiheng-yang
marked this pull request as ready for review
September 14, 2026 11:14
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.
feat(training): add single-node multi-GPU SFT and GRPO
Summary
This PR adds single-node DDP and FSDP2 training to the existing SFT and GRPO pipeline, targeting bf16 LoRA on nvidia gpus.
Each training stage can select an Accelerate YAML profile; omitting the profile keeps the existing in-process launch path and CLI commands.
The local implementation has completed real gpu training checks for both SFT and online GRPO, including checkpoint export.
Launch and checkpoint handling
SFT and GRPO use the same launcher, rank helpers, and checkpoint export code.
Workers check their process count against the selected profile, and launch subprocesses receive an explicit environment so distributed-training variables do not leak into sandbox commands.
Profiles are tracked by content for resume checks and bundled with HF Jobs and prepared submissions.
Older run plans without a launch section remain compatible with the default in-process configuration.
Each FSDP2 profile must request a full state dict so saving produces a portable adapter; the coordinator exports the merged model on CPU after the training workers exit.
Scheduler allocations and site-specific cache paths stay outside the training code.
Training ranks, inference GPUs, and sandbox concurrency are configured separately.
Online GRPO
Each rollout has a unique global ID, and the configured sandbox concurrency is shared across ranks.
Verifier rewards are gathered in rollout order before calculating group advantages, so adding ranks does not change which samples belong to a reward group.
OpenCode can rewrite tool-call history, refresh context, or delegate to another agent.
That makes one flattened transcript an unreliable representation of every sampled action.
The collector therefore saves each model call's exact prompt IDs, completion IDs, and sampled logprobs, then trains those calls as separate causal segments:
Each segment keeps its original rollout's advantage.
Sequence-level importance correction is calculated across all segments of that rollout, and DAPO uses the global sampled-token count for normalization.
Old-policy probabilities are cached before optimization and reused across the corresponding training steps.
Long trajectories are processed one segment at a time, with backward immediately releasing each segment's graph.
Ranks agree on the number of execution slots and use zero-loss dummy slots when needed, keeping FSDP2 collectives aligned without dropping real actions.
This addresses the memory failure seen when all long segments were scored in one batch.
GRPO explicitly loads the pinned causal policy, and the model bridge preserves schema-declared numeric and structured XML tool arguments.
An optional OpenCode step budget applies to the built-in main and subagents; it remains a per-agent soft limit, separate from the overall timeout.
Main files
Python filenames below are under
pipelines/benchflow-task-posttrain/src/posttrainarena/benchflow_pipeline/.config.py,launcher.py,cli.py, andpipeline.py: stage profiles, worker dispatch, timeout settings, and resume checks.distributed.py,sft.py, andcheckpoint.py: rank coordination, SFT execution, adapter saving, and CPU merged export.grpo.py,segmented_rollout.py, andsegmented_trainer.py: distributed collection, exact sampling records, and memory-bounded segment training.model_bridge.pyandopencode.py: tool-argument handling and agent configuration.hf_jobs.pyandsubmission.py: profile packaging for remote jobs and prepared submissions.configs/accelerate/andtests/directories: launch examples and regression coverage.Validation
The full pipeline suite passed on the validated local tree:
362 passed.Regression coverage includes context changes, exact segment preservation, rollout-group mapping, and cached old-policy probabilities; a two-process CPU test also checks unequal segment counts, collective ordering, and gradient equivalence.
SFT checks on real hpc GPUs covered single-process, DDP, and FSDP2 training on small supervised datasets, adapter saving, CPU merged export, and checkpoint reload.
The final online GRPO run used three GPUs: two training ranks and a separate inference GPU.
It ran fresh OpenCode tasks in Apptainer sandboxes, with real verifier rewards and no synthetic rollouts or substituted rewards.
Both modes finished without agent or verifier errors, produced finite training results, and passed the saved-parameter and export-digest checks.
Every successful agent exchange was matched against its persisted token and logprob record.
The final multi-rank online GRPO checks used a local BenchFlow checkout with Apptainer support so agent sandboxes could run on the HPC allocation.
Apptainer is not a dependency of the training implementation; it was the sandbox backend used for this validation.
Related backend work is tracked in benchflow-ai/benchflow#1073; reproducing this run requires the locally modified checkout, not necessarily that PR alone.
Equivalent multi-rank online validation with the unchanged pinned upstream BenchFlow dependency and Daytona remains outstanding.
Earlier Daytona attempts encountered provider-routing errors and service constraints, so we used Apptainer on the HPC allocation to complete the online validation.
The validated scope is single-node, text-only bf16 LoRA; multi-node training, full fine-tuning, quantization, and other GRPO loss variants are outside this validation.
Spend and external systems
The final successful online validation used three HPC GPUs for approximately 1 hour 44 minutes.
A preceding replay used two GPUs for approximately 32 minutes and trained on the unchanged recorded trajectories to verify the memory fix under DDP and FSDP2.
Earlier SFT GPU checks, failed diagnostic attempts, and Daytona Oracle checks also consumed resources; the durations above are not the total development spend.
These experiments used the local integration worktree before the implementation was assembled into this branch.
Model caches, checkpoints, and raw traces remain local and should not be included in the PR.
No hosted-model API was used for the final local-model GRPO run.