Conversation
…stop traning was not received
… better abab pattern detection in generations results to test weight bradcast correctnes, some refactoring
[WIP] Adding tests to vllm actor for Fast-LLM integration
# Conflicts: # pipelinerl/state.py # pipelinerl/vllm1.py
…ck, drop dead code - Coerce samples_processed to int in the preprocessor progress log, avoiding a TypeError before the first SamplesProcessed arrives on the non-Fast-LLM path. - Consolidate the trainer-finished check into TrainerState.is_finished(), replacing three near-identical copies across actor.py and preprocess.py. - Extract a _node_suffix() helper shared by both finetune launchers. - Remove the dead create_engine(cleanup=...) parameter and teardown block (the sole caller always passes cleanup=False) and its now-unused import. - Inline the single-use write_sample_for_fast_llm wrapper. - Type-hint read_fast_llm_events; rename r/gname to full names; regroup vllm1 imports; drop a forward-ref quote, restating comments, and the _inspect alias. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts: # pipelinerl/preprocess.py
- Drop the internal container-registry FQDN from the 'use prebuilt image' step; keep the image tag and reference the internal registry generically. - Genericize the EAI_PROFILE datacenter code to a placeholder. - Fast-LLM's `gspo` branch was deleted after its functionality merged to main; drop the now-broken `git checkout gspo` step so the install instructions work against main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`_run_finetune_fast_llm` derived `experiment_name` from the save_dir path and set
it unconditionally, so the Fast-LLM trainer's wandb run always logged under the
run-dir path (e.g. `pipelinerl_runs/.../finetune`) instead of grouping with the
actor/preprocess runs, which `init_wandb` names `{wandb_name}/{component}`.
Prefer `{wandb_name}/finetune` when a run name is set; fall back to the old
path-derived name otherwise.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…configs - vLLM per-token model-version tagging: producer patches in vllm1.py plus consumers in async_llm.py, llm.py, and rollouts.py. - Preprocessor/state/actor RL metrics: reward and model-version pass-through, completed-step back-pressure, and the data-pipeline logging flag. - GSPO experiment configs (Qwen 0.5B / 7B, DeepSpeed and Fast-LLM variants), the counting task config, and the conf/base.yaml logging flag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jlamypoirier
changed the base branch from
jlp_fast_llm_core
to
jlp_fast_llm_metrics_configs
July 16, 2026 21:47
Name the Fast-LLM finetune wandb run from wandb_name
- conf/counting.yaml: the fast_llm GRPO loss entry had no `type:`, so it fails to dispatch on the Fast-LLM backend (base defines no default loss). Add `type: grpo`. - preprocess.py: the debug data-pipeline log file was opened outside the stream `with` block and never closed. Register it on a contextlib.ExitStack entered by that block so the handle closes on exit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`_run_finetune_fast_llm` derived `experiment_name` from the save_dir path and set
it unconditionally, so the Fast-LLM trainer's wandb run always logged under the
run-dir path (e.g. `pipelinerl_runs/.../finetune`) instead of grouping with the
actor/preprocess runs, which `init_wandb` names `{wandb_name}/{component}`.
Prefer `{wandb_name}/finetune` when a run name is set; fall back to the old
path-derived name otherwise.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- vllm1.py: _create_chat_logprobs captures *args/**kwargs like
update_from_output, so a vLLM signature change disables tagging
instead of crashing at bind time; bounds-guard token_ids[index]
to match top_logprobs[index]; log {error!r} on import failure.
- preprocess.py: hoist `import json` to module top, use the existing
Path import, attribute-access cfg.debug.log_data_pipeline, and use
an identity check for pipeline_log_file.
- math_qwen05_gspo_fllm.yaml: drop inert decay_iterations under a
constant schedule; reword the losses comment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_run_finetune_fast_llm referenced finetune_rank in its multi-node torchrun args, but the name is only bound inside _node_suffix. Define it in the multi-node branch where it is used. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Apply the coarse + fine review findings: - Delete test_actor_error_handling.py — every test reimplemented the actor error-handling logic inline and asserted on the copy, so it could not catch a regression in the real actor. - Drop the generic-path topology matrix (TestWeightUpdateTP2, TestWeightUpdateMultiActor); equivalent multi-topology coverage lives on the Fast-LLM path in test_vllm1_fast_llm_broadcast.py. - Move the EngineManager import out of conftest top level into the factory fixture so the CPU-only unit tests collect without vLLM/torch. - Consolidate the duplicated stream_process_output / kill_process_tree helpers into server_weight_update_utils.py and drop the now-pointless injected stream_process_output_fn parameter. - Remove dead helpers (force_kill_process, check_pattern_detected), unused fixtures/params/imports, and the dead timeout parameter. - Minor typing and style fixes (builtin generics, strict zip, f-string and implicit-Optional cleanups). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts: # tests/conftest.py # tests/distributed_trainer_helper.py # tests/fast_llm_trainer_helper.py # tests/server_weight_update_utils.py # tests/test_vllm1_fast_llm_broadcast.py # tests/test_vllm1_integration.py # tests/test_world_multinode.py # tests/trainer_test_utils.py # tests/weight_update_utils.py
…r exit code - Delete TestPodIPExchange, TestHostfileCreation, TestRedisHostMultiNode: each asserted on a hand-copy of launch.py logic (_simulate_pod_ip_exchange, _compute_streams_host, the hostfile host-list) rather than the real code path, so a regression in launch.py would leave them green. The helper _simulate_pod_ip_exchange stays as setup for TestDeepSpeedCommand, which drives the real _run_finetune_deepspeed. - Assert trainer_proc.returncode in (0, None) after the wait loop in the server / broadcast pattern tests, so a trainer that crashes during final cleanup fails instead of passing on the already-captured pattern. - Fine cleanups: drop unused `import tempfile`, redundant local re-imports (argparse-as-ap, omegaconf, per-function pathlib/sys.path), unused thread handles and loop counter; hoist the broadcast import out of the inner closure; return the dtype string directly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…suite run Running the suite for the first time exposed 11 failures in test_world_multinode.py, all test-setup gaps (not product bugs): - 8× `Missing key wandb_name`: the fast-llm test cfgs (_capture_cmd, _capture_fast_llm_files) omitted wandb.wandb_name, which _run_finetune_fast_llm reads. Add it (None) so the code reaches the torchrun/naming assertions. - 3× `WorldMap has no dns_address_map`: multinode finetune always runs after _exchange_pod_ips (which sets dns_address_map), but _make_world_map produced a pre-exchange map. Set dns_address_map for world_size > 1 in the helper to mirror production. Delete test_deepspeed_multinode_uses_dns_names_without_exchange: its "without exchange" premise is unreachable for multinode, and the after-exchange sibling already covers the DNS-in-filter assertion (plus the no-pod-IP-leak check). Verified on GPU: test_world_multinode + test_launch_process_monitoring now 29 passed. Co-Authored-By: Claude Opus 4.8 <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.
Status: WIP — handover from Denis (2026-05-06)
This branch is not ready to merge. It's the in-progress integration of Fast-LLM as an alternative trainer to DeepSpeed, with weight broadcast to vLLM v1 over a persistent NCCL group instead of HTTP. I'm leaving the integration project — this PR captures everything needed to pick it up.
Read this first:
docs/FAST_LLM_INTEGRATION.md— canonical handover (architecture, per-file changes, glossary, all known issues with file:line citations, testing guide, operations notes, open questions).Stats: 79 commits ahead of
main, ~8 400 insertions / 195 deletions across 35 files (mostly new tests + integration plumbing + handover docs).What works today
gspobranch) trainer launches under torchrun, joins a persistent NCCL broadcast group, and pushes weights to vLLM v1 workers in place. No HTTP weight upload.training_finishedevent over redis → vLLM destroys process group → both sides hit the collective barrier together) —dist.destroy_process_group()no longer hangs.grad_normparity,grpo_new_logprobsmatches step-by-step over a 400-step run (see chart below).Companion Fast-LLM PR
This PipelineRL branch pins to the
gspobranch in Fast-LLM (PR #502). The Fast-LLM PR contains:/num_documents, grad/num_documents²) + SDP loss correction — exact match to DeepSpeed's1/batch_sizedual-factor mathfp32_lm_headflag matching vLLM'sbf16_last_layer_fp32precision (otherwise IS ratios drift)metrics: GRPOMetricsLevelenum (none/basic/with_entropy) — merged from PR #494 (Joel's metrics refactor)Once that PR merges to Fast-LLM
main, the README install step here should be revved fromgit checkout gspo→git checkout mainand this PR rebased onto a freshmain.What's NOT done yet
_prefetch_to_doc_targetovershoot (pipelinerl/actor.py:613). Causes premature run end on long runs (50+ steps). Workaround: bumpmax_train_steps~20%. Real fix: trainer signals "done" instead of actor inferring.pipelinerl/async_llm.py:137-146). Two consecutive aborts can drop a rollout permanently. Allow more retries or evict stuck rollouts.pyproject.tomloverrides (pyproject.toml:81-87). The[tool.uv]block force-overridestransformers>=4.51.0/accelerate>=1.7.0becausetapeagents==0.1.16pins them lower;[tapeagents]extra is broken at runtime. Either bump tapeagents or drop the extra on this branch.rl/ess(effective sample size — diagnostic for data/policy drift).interactive-toolkit:25.12-py3-vllm014rc1redis(PyTorch 25.12, vLLM 0.14.0rc1). Move to the latest base PyTorch + vLLM that both Fast-LLM and PipelineRL support; re-run smoke after.Known issues (with code references)
TimeoutError: No document received after 600snear final steppipelinerl/actor.py:158, 613-614project_actor_samples_target_overshoot_bug.mdin_progressafterattempt=2/2 abortpipelinerl/async_llm.py:137-146project_stall_investigation.mdactor/reward_mean~2 points below DS at step 400project_fastllm_reward_lag_after_gspo_fix.mdCurrent limitation (not a bug):
streams=filesis not implemented foruse_fast_llm=true— Fast-LLM only shipsRedisStreamingDataset. Usestreams=redis. Seeproject_streams_files_not_supported_fast_llm.md.Training curves (400-step run): fast-llm GSPO vs DeepSpeed GSPO
Compared runs:
math_7b_4node_fastllm_gspo_20260505_122944(divisor² + SDP fix)math_7b_ds_fastllm_4node_20260428_135427(matching GSPO config:policy_loss=gspo,epsilon_low=3e-3, 400 steps)new_logprobs— fast-llm matches DS step-by-step (the GSPO loss math fix is correct):actor/reward_mean— fast-llm lags DS by ~2 points at step 400 (open issue):How to verify locally
See
examples/interactive/fast_llm_4node.shandexamples/interactive/ds_4node.sh— both follow the README install.Both run a 2-step smoke and finish in ~10 minutes. Override
MAX_TRAIN_STEPS=Nfor longer runs.Smoke result (last verified 2026-05-06)
59f3b62f084ef7d8Per-step wall time ~80–120 s for both — fast-llm and DS run at comparable speed at this scale.
Code change summary
See
docs/FAST_LLM_INTEGRATION.md§5 "Per-file changes" for the file-by-file table. Highlights:pipelinerl/launch.py: TCPStore pre-creation for broadcast rendezvous (workaround for torchrun client-onlyTORCHELASTIC_USE_AGENT_STORE=True);fast_llm.callbacks.streaming.broadcast.*injection.pipelinerl/state.py: fast-llm event-stream listener thread;samples_processed=0initialization to avoid startup deadlock.pipelinerl/vllm1.py:init_actor_update_group/destroy_actor_update_groupwithWEIGHTS_BROADCAST_PG_NAME;training_finishedhandler for coordinated NCCL teardown.pipelinerl/async_llm.py: rollout retry onvLLM aborted request(weight-update collision).tests/: weight-broadcast tests (test_vllm1_fast_llm_broadcast.py), full vLLM v1 integration (test_vllm1_integration.py), multi-node topology (test_world_multinode.py), actor error handling.Reviewer checklist
This is a draft PR for handover, not for merge. Reviewer should:
docs/FAST_LLM_INTEGRATION.mdend-to-end.bash examples/interactive/fast_llm_4node.shand confirm step 1-2 metrics infinetune/stdout_node0.log.