Repository navigation
Round 15: 1-day full fine-tune on the 1M corpus - #16
Merged
Merged
Conversation
Adds the `ambitious-fullft-4b-1d` arm (Qwen3-4B full FT, 26,000 steps, group 4, prompt 1,536, batch 2 x accum 2 on one L40S) and the three fixes each dead launch exposed: - `_sample_train_records` replaces the whole-corpus `pd.read_parquet`: pass 1 reads only `split` to choose k rows with a fixed seed, pass 2 re-reads in row-group batches keeping just those. Memory scales with `train_contexts`, not corpus size, and `harness_code` (eval's executable twin, never read by training) is not loaded at all. Run usnnr9xmpnnq4ftjqgzn OOMKilled 4x on 1,016,896 rows. - `gradient_accumulation_steps` added to `TunerProfile` and wired into `GRPOConfig`, which never set it. It is how a rung keeps its group size and prompt budget while halving the logits tensor. - `vram_estimate_gib`/`preflight_vram` now take the real parameter count and model full-FT gradients + 8-bit Adam state, plus a 1.25x margin measured against umnzhngvwbf9d6fbhwfz's CUDA OOM. That state allocates on the first optimizer step, so preflight was blind to it. Tests: `test_corpus_sampling.py` pins the bounded read (including that `pd.read_parquet` is never called); `test_round11_arms.py` gains the TRL divisibility and VRAM-fit checks plus a regression that the batch-4 config can never pass preflight again. 263 pass. Research log: `2026-09-16-round-15-fullft-1day.md` with the run ledger (3 dead runs, 1 in flight), the sizing measurements, and findings — including that `flyte run` re-registers trainer resources, so the `RT_TRAIN_*` vars must be exported for both commands. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.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.
Round 15 asks what a full fine-tune does with a real training budget on a real corpus. Round 11's
r11-fullft-4bbeat LoRA on fit (79% vs 53%) on 300 steps; this arm gets 26,000 steps on the 1,016,896-row round-15 corpus — the 1M target round 12–14 left open is met.The training run (udrtv5nj7dcth86qdfn6) is in flight. Nothing about full FT vs LoRA is claimed in this PR — what it ships is the arm plus the three fixes each dead launch exposed.
The arm
AMBITIOUS_FULLFT_4B_1D— Qwen3-4B full FT, 26,000 steps, group 4, prompt 1,536, batch 2 × accum 2, one L40S, 48Gi. Every number is derived from a prior run's measurement; the arithmetic and both OOM calibration points are recorded in the profile comment.The three fixes
_sample_train_recordsreplaces the whole-corpuspd.read_parquetgradient_accumulation_stepsadded toTunerProfile, wired intoGRPOConfig(which never set it)vram_estimate_gib/preflight_vramnow model full-FT grads + 8-bit Adam statesplitcolumn to choose k rows with a fixed seed; pass 2 re-reads in row-group batches keeping just those. Memory scales withtrain_contexts, not corpus size.harness_code— eval's executable twin, never opened by training — is not read at all. Materializing 10⁶ rows to train on 26,000 was always waste: GRPO consumes one prompt per step.Findings worth carrying forward
flyte runre-registers trainer resources, not justflyte deploy.train_resources()readsRT_TRAIN_GPU/RT_TRAIN_MEMORYat import, so the env is serialized from whichever process registers it. Setting the vars on the deploy alone put the first run on the 10Gi/T4 defaults while the deployment said L40S/48Gi. ExportRT_TRAIN_*for both commands. The profile'strain_gpu/train_memoryare advisory — preflight compares against them, they do not request anything.Step time tracks sequences per optimizer step, not nominal batch size. The original 18,000-step budget was extrapolated from a 3.57 s/step measurement taken at batch 8 / ngen 8. This arm puts four sequences through a step and measured 2.92 s/step over 839 steps — so 18,000 was ~16h, not a day. Budget is now 26,000.
Tests
tests/test_corpus_sampling.py(8 cases) pins the bounded read — including, precisely, thatpd.read_parquetis never called, since a memory assertion in a unit test would report 0.4MB for the path that killed a 10Gi pod.tests/test_round11_arms.pygains the TRL divisibility check, the VRAM-fit check, and a regression that the batch-4 config can never pass preflight again. 263 pass.Still open
6654000) are still unverified on a live artifact — the first real card will be this run'stuner-checkpoint.uk9pj886sxmw9sqnhgrtremains unevaluated (carried from round 12–14).🤖 Generated with Claude Code