Checking main's conflicts with the Tmax branch#1741
Conversation
* Add dr tulu script, fixes for it. * fix * Add per-tool pool_size_override and update DR-TULU script Add pool_size_override field to BaseEnvConfig so individual tools can use a different pool size than the global --pool_size. S2 search gets 100 actors while serper/jina get 256. Made-with: Cursor * Fix pool_size_override dataclass inheritance error Move pool_size_override out of BaseEnvConfig (which caused "non-default argument follows default argument" in subclasses like PythonCodeToolConfig) and instead pop it from the raw config dict before constructing the dataclass. Made-with: Cursor * Add sequence_parallel_size 2 to DR-TULU script Made-with: Cursor * fix * Fix CI: remove unused type: ignore, add CHANGELOG entry Made-with: Cursor * Switch to Qwen3.5-4B, extract last <answer> tag for rubric scoring Made-with: Cursor * Fix ruff formatting in grpo_fast.py Made-with: Cursor * Fix ty type check: use ty: ignore for ChatCompletionRequest tools arg Made-with: Cursor * Fix DataPreparationActor hanging on shutdown DataPreparationActor.shutdown_requested was checked in the data preparation loop but never set to True by anyone. During cleanup, cleanup_training_resources signaled ActorManager (for vLLM actors) but never told the DataPreparationActor to stop, causing it to spin forever in the "waiting for step to be consumed" loop after training completes. Add request_shutdown() method and call it during cleanup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add changelog entry for DataPreparationActor shutdown fix Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Avoid deadlock: fire-and-forget request_shutdown instead of ray.get() Using ray.get() can deadlock if the actor's main thread is blocked in get_data waiting on the background thread, which is itself blocked on the queue. The ShutdownSentinel that unblocks the queue is pushed later in cleanup, but would never be reached. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Tighten comment and narrow exception handler Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add executor timeout and vLLM actor thread exit on shutdown - executor.shutdown: use 300s timeout per thread instead of blocking forever, so ray.shutdown() is always reached - process_from_queue: use get(timeout=1.0) and check _should_stop() to exit instead of blocking forever on completions - _prefetch_worker: break on should_stop instead of spinning Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix attention leakage in packed sequences with HF flash attention When attention_mask is non-None, HF's _flash_attention_forward treats the entire packed sequence as one document, bypassing position_ids-based sub-sequence isolation. Detect packed sequences via position_ids resets and pass attention_mask=None so flash attention creates proper cu_seqlens per sub-sequence. Made-with: Cursor * Add tool_call_timeout to prevent stuck rollouts from blocking training Tool calls (e.g. browse_webpage) can hang indefinitely if the target URL never responds. This blocks the rollout coroutine, which prevents inference results from flowing, which stalls the entire training step. Wrap target.step.remote() with asyncio.wait_for(timeout=120s). On timeout, the rollout records the error and continues. The timeout defaults to 120s and is configurable via the tool_call_timeout parameter on LLMRayActor. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Increase default tool_call_timeout to 300s Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix process_from_queue exiting during weight sync process_from_queue must not break on _should_stop() — that flag is temporarily True during every weight sync. If the completion queue happens to be empty for 1s during a weight sync, the thread exits permanently and results are never processed again. Revert to unconditional loop — the thread will be killed when the Ray actor is shut down. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Revert _prefetch_worker to original sleep-and-continue on should_stop Same issue as process_from_queue: breaking on _should_stop() exits the thread permanently during weight sync. Restore original behavior where should_stop causes a sleep-and-continue (pause), not an exit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add temporary verbose logging to diagnose weight sync hang TODO(debug): remove once hang is diagnosed. Logs added at: - weight_sync_thread: each phase (set_should_stop, send RPCs, wait) - broadcast_to_vllm: entry/exit per rank - broadcast_weights_to_vllm: GatheredParameters entry/exit - _send_to_vllm: RPC send, first/all NCCL broadcasts - LLMRayActor.update_weights_batch: receive, collective_rpc Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix weight sync deadlock: barrier before exiting GatheredParameters Rank 0 does NCCL broadcasts to vLLM engines inside GatheredParameters, while ranks 1-7 return immediately. Without a barrier, ranks 1-7 start exiting GatheredParameters (itself a collective to re-partition params) while rank 0 is still broadcasting on model_update_group. This causes the exit collective to deadlock intermittently. Add torch.distributed.barrier() before exiting the context so all ranks wait for rank 0 to finish the vLLM broadcasts first. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix weight sync deadlock: use per-param gathering for DeepSpeed stage 3 Gathering all params at once (gather_whole_model=True) with DeepSpeed stage 3 deadlocks intermittently: rank 0 does NCCL broadcasts on model_update_group inside GatheredParameters, and the exit collective (re-partition) races with these broadcasts, causing a deadlock. For DeepSpeed stage 3, use the per-parameter gathering path instead. Each param is gathered individually, broadcast to vLLM, then released. This avoids the interleaving of collectives on different NCCL groups. FSDP continues to use gather_whole_model since it doesn't have the same issue. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Remove weight sync timeout to allow debugging with stack traces Revert broadcast_weights_to_vllm to original gather_whole_model logic and remove the health_check_fn timeout so the job stays alive when the weight sync hangs, allowing inspection via ray stack traces / debugger. TODO(debug): restore timeout once the deadlock root cause is found. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add NCCL warmup broadcast after model_update_group init The model_update_group NCCL communicator intermittently hangs on its first broadcast. NCCL lazily establishes GPU-to-GPU connections, and the lazy init can fail silently on cross-node communicators. Add a warmup broadcast immediately after init_process_group to force NCCL to establish connections eagerly. If the warmup fails, the job fails fast at startup instead of hanging hours into training. Also removes the weight sync health_check timeout to allow debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add sync broadcast before weight param broadcasts to prevent race Rank 0 fires update_weights_batch RPCs to engines then immediately starts NCCL broadcasts. If one engine is slow to enter the receive loop (EngineCore busy with inference), the rapid-fire 426 broadcasts can desynchronize NCCL and cause an intermittent deadlock. Add a dummy sync broadcast as the first operation: engines do a receive in update_weights_batch before processing real params, and rank 0 does a matching send in _send_to_vllm before starting param broadcasts. This ensures all 9 ranks are synchronized before the real work begins. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Guard process_tool_tokens against non-string tool outputs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add weight sync retry with NCCL timeout and process group recreation The NCCL broadcast for weight sync intermittently deadlocks. Previously this hung the job for hours (NCCL timeout was 1800 minutes). Changes: - Set model_update_group NCCL timeout to 120s (was 1800 min) - Add retry logic (3 attempts) in broadcast_to_vllm: on NCCL timeout, destroy the stuck process group, create a new one on a fresh port, and retry the broadcast - Restore health_check_fn timeout at 600s (enough for NCCL timeout + process group recreation + retry) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Harden process_tool_tokens against untokenizable tool outputs Strip null bytes and catch TypeError from the fast tokenizer's Rust backend, which rejects certain Unicode sequences that Python's str type accepts. Fall back to empty tokens on failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * up the pool timeout * Revert NCCL warmup broadcast and weight sync retry changes Remove the NCCL warmup broadcast, dummy sync broadcast in _send_to_vllm, weight sync retry with process group recreation, short NCCL timeout, and verbose debug logging. Restore original broadcast_to_vllm and weight_sync_thread behavior from main. Made-with: Cursor * Revert request_shutdown changes and set tool_call_timeout to 1800s Remove the DataPreparationActor shutdown_requested/request_shutdown cooperative shutdown mechanism and the ray.kill() call in cleanup. Also set default tool_call_timeout to 1800s (30 min). Made-with: Cursor * Set tool_call_timeout default to 1800s, simplify packed sequences comment Made-with: Cursor * Restore data_loader.py to match main (keep shutdown_requested) Made-with: Cursor * Remove attention_mask from forward_for_logprobs, restore executor.shutdown(wait=True) HF constructs the correct 3D mask from position_ids internally, so we don't need to pass attention_mask. Also revert the executor.shutdown change back to wait=True. Made-with: Cursor * Revert forward_for_logprobs attention_mask changes Moved to a separate PR (#1617). This keeps the dr-tulu-replication branch focused on DR-TULU replication changes. Made-with: Cursor * Use walrus operator for answer extraction in RubricVerifier Apply reviewer suggestion for cleaner control flow. Made-with: Cursor * Make pool_size a field on BaseEnvConfig Add pool_size as a kw_only dataclass field on BaseEnvConfig, so users can set it directly in --tool_configs JSON instead of via a magic "pool_size_override" key. Using kw_only avoids the dataclass inheritance issue with subclasses that have non-default fields. Made-with: Cursor * Move tool_output string coercion into ToolParser base class The parser is responsible for producing a string, so it should coerce inputs to strings itself. Make format_tool_outputs a concrete template method that coerces inputs then delegates to a protected _format_tool_outputs implemented by subclasses. Made-with: Cursor * Move formatted output str coercion into parser; revert queue timeout Move the isinstance(formatted_output, str) check into the ToolParser template method. Also revert the completion_queue.get(timeout=1.0) change since the original blocking .get() was intentional. Made-with: Cursor * Restore # avoid OOM comment in broadcast_to_vllm Made-with: Cursor * Move null-byte stripping into ToolParser.format_tool_outputs Made-with: Cursor * Clean up Qwen 3.5 parsers and simplify tool pool config - Match Qwen 3.5 chat template: tool responses wrapped in <tool_response> with user role, generation prompt starts <think>\n - Remove vllm_qwen3_coder parser (confusing, unused) - Simplify create_tool_pools to pass pool_size through kwargs - Update CHANGELOG to specify Qwen 3.5 4B Made-with: Cursor --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: root <root@saturn-cs-aus-237.reviz.ai2.in>
) * Fix verify_sentence_constraint missing ! as a sentence terminator The regex used to split a response into sentences only treats "." and "?" as terminators: re.split(r"(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s", text) For any response containing "!", the count was too low, e.g. "Hello! How are you? I am fine." was counted as 2 sentences instead of 3. That silently biased the `verify_sentence_constraint` verifier (wired into `IF_FUNCTIONS_MAP`), causing IFEval-style "around / at least / at most N sentences" checks to fail on responses with exclamations. Fix: extend the positive lookbehind alternation to include "!". The negative lookbehinds that guard abbreviations (e.g. "U.S.", "Mr.") are untouched, so "Go to the U.S. now! What next?" still splits cleanly on the "!". * Add CHANGELOG entry for #1612 --------- Co-authored-by: Hamish Ivison <hamishivi@gmail.com>
…#1586) * Harden grpo_fast startup resource checks * Add changelog entry for startup checks PR * Simplify grpo_fast startup resource helpers
…ipts. (#1626) * Add --artifact_ttl flag to mason.py and set to 1d for debug scripts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Refactor mason.py auto-path construction to use pathlib Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Defer str() conversion of pathlib paths until use in mason.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…teLLM helper (#1587) * Route LLM judge through guarded LiteLLM helper * Add changelog entry for judge helper fix * Validate LiteLLM helper inputs --------- Co-authored-by: Hamish Ivison <hamishivi@gmail.com>
* cleans up staleness code * Cleaned up code * Fix CI: add model_steps/model_step to test fixtures and CHANGELOG entry Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove model_step kwarg from broadcast_weights_to_vllm test call — new vLLM native API no longer takes it Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Thread model_step through update_weights RPC to avoid separate set_model_step call Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make WeightSyncTrigger step non-optional; drop fallback Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Require initial step in WeightSyncTrigger constructor Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use resume_training_step - 1 for initial WeightSyncTrigger; drop redundant resume arg in thread Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix vLLM weight transfer API + require training_step in accumulate_inference_batches Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix model_step race and pipe DataPreparation metrics + beaker config to OLMo-core wandb Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove ceres cluster from single_gpu_grpo.sh; availability too slow Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Test: set async_steps=1 to verify model_step stamping bug Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Simplify: thread model_step through update_weights kwarg; drop ray.get waits Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Simplify setup_model_update_group: unify IPC/NCCL init into single codepath Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Split update_weights into vLLM-facing update_weights(dict) and trainer-facing apply_weight_update(update_info, model_step) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop apply_weight_update; NCCL path reuses update_weights + set_model_step Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fold model_step into update_weights RPC; drop separate set_model_step call on NCCL path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Fix weight sync init on resume; add fingerprint verification Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restrict weight-sync fingerprint to params with shared HF/vLLM names Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use IPC backend in GPU fingerprint test to match engine config Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Simplify GPU fingerprint test: verify fingerprint matches pretrained weights without broadcast Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Initialize vLLM weight sync before training loop so resumed runs push checkpoint weights before first rollout Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Accept IPC update_info dict in LLMRayActor.update_weights Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Replace toothless weight-sync tests with real divergent-weight broadcast test Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Warm up learner with dummy forward before first weight sync to materialize DeepSpeed Stage 3 params Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove weight-sync fingerprint debugging code Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up code * Add CHANGELOG entry for PR #1627 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Added script * set no-auto_dataset_cache * Address PR review: fix qwen3_4b_dapo_math.sh args and default image Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add --eval_top_p override for eval generation config Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Fix installation as third party dependency * PR comment fix * Changelog
…ion (#1622) * Extract numpy SFT conversion helpers into open_instruct.numpy_dataset_conversion Moves the HF-to-OLMo-core numpy mmap conversion logic out of scripts/data/convert_sft_data_for_olmocore.py and into a new module open_instruct/numpy_dataset_conversion.py so it can be imported by downstream callers (e.g. the upcoming OLMo-core SFT main). The CLI script keeps its argument surface and just delegates to the library. Split out of #1620 (match-sft). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CHANGELOG entry for numpy dataset refactor PR #1622 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add numpy_dataset_conversion tests and byte-for-byte Beaker verification harness Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Reduce verify script to 1 GPU to avoid Jupiter queue backlog Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use uv run prefix for huggingface-cli and python in verify script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use python snapshot_download instead of missing huggingface-cli in verify script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Pass tokenizer repo ID directly to avoid separate download step Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add download_hf_repo.py helper and restore local tokenizer path in verify script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Temporarily point 7b_think_sft_tokenization.sh to olmo-hybrid-fresh dir Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Point tokenization script to open-instruct-dev workspace Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make tokenization script preemptible Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use download_hf_repo.py instead of missing huggingface-cli in tokenization script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix get_tokenizer_tulu_v2_2 for transformers v5 by using path substring instead of AutoConfig Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Switch hybrid SFT tokenization to CPU-only and add --resume Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add incremental binary checkpoint + local byte-for-byte verify/benchmark harness Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add small-scale tokenization verify launch script, checkpoint timing logs, beaker description updates Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Updated code with verification * Added doc * Minimize diff in convert_sft_data_for_olmocore.py docstring formatting Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Replace download_hf_repo.py helper with hf download CLI Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr * cleaned up pr * Trim test_numpy_dataset_conversion.py to core regression tests Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up PR * Revert checkpoint format to single-file JSON; incremental binary moved to separate PR Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* Extract numpy SFT conversion helpers into open_instruct.numpy_dataset_conversion Moves the HF-to-OLMo-core numpy mmap conversion logic out of scripts/data/convert_sft_data_for_olmocore.py and into a new module open_instruct/numpy_dataset_conversion.py so it can be imported by downstream callers (e.g. the upcoming OLMo-core SFT main). The CLI script keeps its argument surface and just delegates to the library. Split out of #1620 (match-sft). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CHANGELOG entry for numpy dataset refactor PR #1622 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add numpy_dataset_conversion tests and byte-for-byte Beaker verification harness Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Reduce verify script to 1 GPU to avoid Jupiter queue backlog Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use uv run prefix for huggingface-cli and python in verify script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use python snapshot_download instead of missing huggingface-cli in verify script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Pass tokenizer repo ID directly to avoid separate download step Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add download_hf_repo.py helper and restore local tokenizer path in verify script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Temporarily point 7b_think_sft_tokenization.sh to olmo-hybrid-fresh dir Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Point tokenization script to open-instruct-dev workspace Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make tokenization script preemptible Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use download_hf_repo.py instead of missing huggingface-cli in tokenization script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix get_tokenizer_tulu_v2_2 for transformers v5 by using path substring instead of AutoConfig Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Switch hybrid SFT tokenization to CPU-only and add --resume Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add incremental binary checkpoint + local byte-for-byte verify/benchmark harness Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add small-scale tokenization verify launch script, checkpoint timing logs, beaker description updates Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Updated code with verification * Added doc * Minimize diff in convert_sft_data_for_olmocore.py docstring formatting Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Replace download_hf_repo.py helper with hf download CLI Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr * cleaned up pr * Trim test_numpy_dataset_conversion.py to core regression tests Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up PR * Revert checkpoint format to single-file JSON; incremental binary moved to separate PR Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use incremental binary checkpoint for tokenization resume Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove legacy test_checkpoint.py (broken under new incremental checkpoint API; covered by test_numpy_dataset_conversion.py) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Refactor save_checkpoint for readability; switch checkpoint API to pathlib.Path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Raise in _truncate_to on missing/undersized checkpoint files to catch silent corruption Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Added doc * Added doc * removed docs * Use np.fromiter + itertools.islice to avoid list slice copy in save_checkpoint Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restore docs/verify-tokenization.md Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CHANGELOG entry for #1633 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…laude Opus 4.7 <noreply@anthropic.com> (#1637)
…r. (#1631) * Stream SFT tokenization to disk with batched numpy iter Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr * Vectorize attention-mask assert and drop duplicate beaker description call Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Shrink tokenization diff: drop dead code and unused helpers Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Match main's checkpoint file layout for tokens/labels/boundaries Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Shrink tokenization diff: restore main's helpers, keep only batched-numpy collect loop Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Doc: reference existing origin/main tokenization golden run Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restore 30s periodic Beaker description updates in tokenization collect loop Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Stream SFT tokenization to partial bin files; derive stats from disk at end Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Set utf-8 encoding on gzip metadata writer for cross-platform reproducibility Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Refactor numpy_dataset_conversion to pathlib.Path throughout Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up tests * Simplify numpy_dataset_conversion: drop narration docstrings and dead state Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add PR 1631 link to CHANGELOG entries Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address PR #1631 review: clear stale partial files on missing-file resume, avoid int64 labels copy in stats Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
#1620) * Extract shared OLMo-core config classes and helpers into olmo_core_utils.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add OLMo-core SFT implementation with single-GPU and multi-node debug scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Remove unused ty: ignore comment in mix_data.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use training config for weight_decay and max_grad_norm in OLMo-core SFT Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Cleaned up PR * Change TrainingConfig.max_grad_norm from float=-1 sentinel to float|None=None Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Cleaned up PR * Revert max_grad_norm type change (moved to separate PR) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use module-level imports for single-use olmo-core objects in olmo_core_finetune.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use module-level imports for open_instruct objects in olmo_core_finetune.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update docs to cover in-repo OLMo-core SFT implementation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use typed enums/literals for ac_mode and cp_strategy, add validation for unknown modes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * now, we don't import vllm into data_loader.py * clean up PR * Added a test that everything matches. * Added data * Fix PackedSFTCollator missing 'index' key needed by HFDataLoader overflow tracking Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Match OLMo-core SFT experiment: OBFD packing + numpy RNG ordering Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add .claude/scheduled_tasks.lock to gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix get_tokenizer_tulu_v2_2 crash on tokenizer-only repos and add --chat_template_name olmo to match script Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Increase distributed timeout to 1h for large dataset processing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use flash_2 attention backend for ring CP compatibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add ring-flash-attn dependency for flash_2 context parallelism Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use ulysses CP strategy (compatible with flash_3 auto-detect on H100s) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix ephemeral_save_interval must be less than save_interval Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add debug logging for first batch tensor verification Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use global OBFD packing in HFDataLoader to match numpy NumpyFSLDataLoader output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Remove redundant dataset.shuffle() - instance shuffling now handled by _reshard_with_packing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch olmo_core_finetune.py to numpy pre-tokenized dataset path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix pre-existing ty errors in dataset_transformation and parsers Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Match reference experiment 01KNMEJKEZNJKZH9QWQW8CS0JW exactly Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Force flash_2 attn backend (ring CP requires flash_2, not flash_3) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add Qwen3-0.6B SFT parity test: pure olmo-core vs open-instruct (3 steps, 1 GPU) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix parity scripts: flash_2 for reference, drop cp_degree=1 for open-instruct Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Load HF Qwen3-0.6B weights in reference SFT script to match open-instruct Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Align reference with open-instruct: reshuffle(epoch=1) before fit Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Bump reference to 4 steps to test off-by-one hypothesis Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove first-batch debug peek in olmo_core_finetune (consumed a batch) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert reference parity test to 3 steps Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add full 2-epoch 7B match script for experiment 01KNMEJKEZNJKZH9QWQW8CS0JW Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add ring_flash_attn / flash_attn import diagnostic + restore reference CP config Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Patch ring-flash-attn adapters import so package loads under transformers>=5 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use importlib.find_spec to locate ring_flash_attn (avoid importing broken package) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add ulysses-CP variant of 7B full SFT for MFU/loss comparison Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Switch CP strategy to ulysses, drop ring-flash-attn dependency Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add docs/match-sft.md summarizing the reference-SFT parity investigation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix ty errors after merge: drop unused parsers.py ignore, guard None max_grad_norm Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove match-sft investigation scaffolding and unrelated .gitignore Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop unused PackedSFTCollator/OBFDCollator and dependent data_loader/test changes Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up PR * Revert parsers.py ty ignore removal (moved to #1621) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert get_tokenizer_tulu_v2_2 changes unrelated to SFT parity Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert olmo_core_train_modules.py changes (moved to finbarr/small-refactor) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert cosmetic changes to convert_sft_data_for_olmocore.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr * Share setup/scheduler/callback helpers between SFT and DPO olmo-core trainers Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop selected_modules AC mode; use budget-mode only to match DPO/GRPO Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert "Drop selected_modules AC mode; use budget-mode only to match DPO/GRPO Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>" This reverts commit f71cc2e. * Restore origin/main's build_ac_config signature (scalar args, no selected_modules) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop DatasetConfig.dataset_path; require pre-tokenized numpy SFT cache on Weka Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CI: ty path type + CHANGELOG entry for #1620 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address PR #1620 review: tokenizer-derived vocab, cache integrity, HF detection Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use meta init_device for HF checkpoints in olmo_core_finetune Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Centralize numpy SFT file globs * TEMP: PYTHONPATH=/stage in oc_sft.sh for meta-init verification (revert me) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert pyproject packaging change from #1634/#1637; drop temp PYTHONPATH workaround Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add oc_sft_cache.sh for CPU-only tokenization cache job Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Updates main experiment script. * updated script * Pass BEAKER_IMAGE via env var instead of positional arg. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Simplify script invocation in build_image_and_launch.sh; BEAKER_IMAGE is already exported. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert BEAKER_IMAGE env-var change; align qwen3_4b_dapo_math.sh with existing positional-arg pattern. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Add scripts/submit_eval_jobs_new.py to submit olmo-eval-internal jobs via Beaker. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up script * Address PR review: dedup CHANGELOG, sanitize names, gate Weka mounts, use safe_dump. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address PR review: rename submit_eval_jobs scripts; add --olmo_eval_ref; deprecate old script. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Point auto-launched evals at submit_eval_jobs_old.py to keep existing flag set working. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add PR link to CHANGELOG entry. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* now running with urgent * Trim default-valued args from qwen35_4b_dapo_math.sh; fix qwen3_4b_dapo_math.sh image positional leak Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make workspace overridable in qwen3_4b_dapo_math.sh; default to ai2/open-instruct-dev Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Support comma-separated pairs in --remap_verifier; route aime/brumo eval to math verifier Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert "Support comma-separated pairs in --remap_verifier; route aime/brumo eval to math verifier Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>" This reverts commit cf82a70. * Point eval to allenai/{aime,brumo}_2025_openinstruct (republished with dataset=math) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Added oc script * Map Qwen/Qwen3-4B-Base to qwen3_4B config in olmo-core path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add GRPO epoch sweep (2, 4) for qwen3-4b DAPO math Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Force full FSDP sharding in qwen3_4b_dapo_math_oc.sh to fit in 8xH100 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add activation_memory_budget=0.5 to olmo-core script to enable activation checkpointing Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Plumb compile_model through GRPOTrainModule so activation checkpointing works Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add TORCH_LOGS + NCCL flight recorder envs to debug grpo olmo-core hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Diagnostic: disable compile_model and lower pack_length to isolate grpo.py hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Diagnostic: reduce response_length to satisfy pack_length assertion Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restore oc.sh to match math.sh hyperparams (response/pack_length, AC enabled) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Diagnostic B: per-actor TORCHINDUCTOR_CACHE_DIR to isolate inductor cache lock contention Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Diag C: log sleep ENTER/EXIT with active_tasks count to trace weight sync hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Diag D: log post_step + broadcast_weights_to_vllm per-rank per-block to find hang location Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix FSDP2 weight-sync deadlock: whole-model summon + include embeddings/lm_head Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix Qwen3-4B config map: qwen3_4B -> qwen3_4b (TransformerConfig uses lowercase b) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix qwen3_4B config name casing in OLMO_MODEL_CONFIG_MAP Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use grpo_fast.py in qwen3_4b_dapo epoch sweep to avoid FSDP2 weight-sync hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix GRPO double optim_step: override optim_step/zero_grads as no-ops Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Temp: restrict sweep to epochs=4 only for relaunch Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert: restore sweep to epochs=[2, 4] Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add dist.barrier() in VLLMWeightSyncCallback + distributed debug env for grpo.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove redundant entry barrier in VLLMWeightSyncCallback; keep exit barrier to prevent rank desync into gloo bookkeeping collective Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add phase-entry logging to weight sync + NCCL heartbeat timeout to pinpoint hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use logger.warning for weight-sync/post_step phase markers so non-zero ranks aren't suppressed Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove TORCH_LOGS flood so phase-marker warnings can flush through stdout Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use print(flush=True, file=stderr) for phase markers so buffered stdout can't swallow them Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Disable Ray log dedup to see phase markers on all ranks Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix FSDP2 weight sync deadlock: non-zero ranks must participate in unshard/reshard collectives Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add [DIAG] diagnostics for vLLM weight-sync hang investigation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: weight-sync-grpo-oc debugging notes Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add deeper vLLM-side diagnostics for update_weights hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * more diagnostics * Move update_weights async wrapper out of LLMRayActor class to preserve threaded-actor semantics Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix FSDP2 weight-sync dtype mismatch: collect metadata after unshard so bf16 buffers match NCCL send Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: weight-sync-grpo-oc updated with dtype fix (Bug #2) and open sleep/pause bug (Bug #3) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Skip engine update RPC wait in grpo.py post_step when inflight_updates=True, mirroring grpo_fast.py. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * [DIAG-B] Trace vllm Worker.update_weights entry to locate weight-sync hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * grpo: fire initial vLLM weight sync before trainer.fit() to match grpo_fast Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add torch.cuda.synchronize() after FSDP2 unshard before NCCL broadcast to vLLM Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Set CUDA device to 0 before NCCL weight broadcast in grpo.py paths to match grpo_fast Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: inject worker_extension_cls so DIAG-B patches land in vLLM worker subprocess Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: instrument initialize_layerwise_reload to pin worker.update_weights hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: faulthandler watchdog in vllm worker for weight-sync hang Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: pre-finalize cuda.synchronize + warmup forward in run_initial_weight_sync Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * FIX: torch.cuda.synchronize() after trainer_send_weights before FSDP2 reshard to drain NCCL sends Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: drop warmup forward to test if illegal access is caused by it Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: add post-clone sync to bisect illegal access in weight broadcast Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: enable CUDA_LAUNCH_BLOCKING and per-25 broadcast index logging Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Unshard root FSDP module too in broadcast_weights_to_vllm Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Strip weight-sync diagnostic instrumentation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Unify LLMRayActor.update_weights signature with IPC calling convention Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleane dup PR * cleaned up PR * cleaned up PR * cleaned up PR * cleaned up PR * Drop redundant barriers and pre-broadcast cuda calls in olmo-core actor Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up PR * Match grpo_fast metrics in grpo.py: optim/grad_norm, timing, MFU/MBU, weight-sync stats Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restore StreamingDataLoaderConfig annotation on GRPOTrainModule.streaming_config Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Switch oc dapo math script to open-instruct-dev workspace at urgent priority Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use locally-built image when launching oc dapo script via build_image_and_launch.sh Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make streaming_config required on GRPOTrainModule and drop unused epoch metric Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Minor cleanup in VLLMWeightSyncCallback.post_step Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop vllm_engines empty-list guards in grpo.py since vllm_engines is always non-empty Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * less defensive checks * Simplify StepTimingCallback and drop unused inflight_updates from VLLMWeightSyncCallback Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use per-actor ray_get_with_progress timings for weight_sync stats in VLLMWeightSyncCallback Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Share weight_sync_stats helper between grpo_fast.py and VLLMWeightSyncCallback Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Extract grpo_utils.perform_weight_sync from grpo_fast and VLLMWeightSyncCallback Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix ty type checks: type vllm_engines list and ignore unused-ignore-comment Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address PR #1649 review comments: revert IPC rank-0 guard, type update_info, drop deepspeed_stage from qwen script Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update ray_get_with_progress docstring Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CI: drop unused data_types import and add PR URL to CHANGELOG entry Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make LLMRayActor.update_weights model_step optional for IPC path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix MetricsTracker usage in grpo_fast: use __setitem__ instead of update() Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add MetricsTracker.update() and use it in grpo_fast Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix test_post_step: set trainer_mock.global_step so real Callback.step property works Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Switch multi_node_grpo.sh from deepspeed_stage 2 to FSDP (8x2 shard) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Reserve 8 GPUs for vllm in multi_node_grpo.sh: shard-only FSDP, single-node learners Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restore is_rank_0 guard on IPC broadcast to fix multi-rank FSDP deadlock Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Guard np reductions in perform_weight_sync against empty actor_sync_times Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * TEMP: large_test_script.sh sequence_parallel_size=1 to test SP hypothesis Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use TransformerDataParallelWrappingStrategy.full to FSDP-shard lm_head and embedding_norm Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * DIAG: add per-rank CUDA memory snapshots to GRPO train_batch and setup Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Try activation_memory_budget=0.25 in multi_node_grpo.sh Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Match large_test_script.sh: Qwen2.5-7B, vllm 4 engines TP=2 in multi_node_grpo.sh Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Switch multi_node_grpo.sh to Qwen3-8B (olmo-core does not support Qwen2.5) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove memory instrumentation from grpo olmo-core path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Add dynamic versioning based on git tags * Changelog * Apply suggestion from @gemini-code-assist[bot] to fix potential version import error Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Finbarr Timbers <finbarrtimbers@gmail.com>
… `combine_processed_results`. (#1614) * Split accumulate_inference_batches into process_single_result and combine_processed_results Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rename ProcessedResult to Group and deduplicate per-query fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rename combine_groups to make_batch_from_groups Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Remove redundant asserts in make_batch_from_groups (already checked in process_single_result) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Minimize diff: revert cosmetic changes (type annotations, logging style, blank lines) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rename loop variable pr to group in make_batch_from_groups Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * cleaned up PR * Narrow GenerationResult.logprobs and start_time types to non-optional, removing unnecessary None asserts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * cleaned up pr * Simplify make_batch_from_groups: drop dead branches, pass filter counters as kwargs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Set SETUPTOOLS_SCM_PRETEND_VERSION in Dockerfile to fix build after #1636 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…s). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> (#1659)
* Log filtered prompts at INFO and add batch/filtered_prompts_pct metric Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add PR link to changelog entry Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Update Beaker budget from ai2/oe-adapt to ai2/oe-omai Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix PR number in CHANGELOG entry Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Add time/per_group_wall_time metric (mean per-group generation wall time). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address review: running sum for per-group wall time; move changelog entry to Added. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Skip empty batches in OlmoCoreDataLoader to match grpo_fast invariant. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Resample on all-filtered batches instead of yielding empty CollatedBatchData. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add PR link to CHANGELOG entry. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert "Resample on all-filtered batches instead of yielding empty CollatedBatchData. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>" This reverts commit e22337b. * Revert "Skip empty batches in OlmoCoreDataLoader to match grpo_fast invariant. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>" This reverts commit d94a564. * Resample filtered batches in DataPreparationActor; unify grpo/grpo_fast empty-batch handling. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add PR link to CHANGELOG entry. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove per-group wall time metric. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Handle empty filtered batches before packing * Unify empty-batch check: move mask_truncated_completions filter next to zero-std check in DataPreparationActor. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Extract maybe_mask_truncated_completions helper; check result is None immediately. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ection (#1650) * Add IcePop to GRPO: zero per-token loss when train/infer mismatch ratio is outside [1/β, β]. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Enable IcePop in qwen3_4b dapo math experiment script. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Shift BEAKER_IMAGE positional in qwen3_4b script so it isn't forwarded as a stray arg via $@. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix IcePop: reweight in-range tokens by ρ (paper eq. 2), use independent α/β with paper defaults (0.5, 5.0). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Track per-boundary IcePop drop fractions (val/icepop_drop_low_frac, val/icepop_drop_high_frac). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add IcePop training collapse postmortem doc. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * updated timing * Unify TIS/IcePop into a single RhoCorrection abstraction shared by grpo_fast and olmo_core paths. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address PR review: restore checkpoint-state on empty steps; use explicit drop flags for icepop_drop_frac. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up PR * Collapse IcePop bounds to a single beta (range [1/beta, beta]) and log val/rho_hist as a wandb histogram across grpo_fast and olmo-core paths. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove duplicate prompt/response length extraction to minimize diff vs main. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Move non-IcePop changes (eval script tweaks, checkpoint_state refactor) off this branch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Simplify rho correction: compute ratio once, dedupe histogram accumulation across trainers. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Delete compute_icepop_mask; route test through compute_rho_correction. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr * Address PR review: aggregate token counts across DP ranks, gate rho histograms to rank 0, token-weight icepop drop metrics. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Replace icepop_beta with separate icepop_lower_bound/icepop_upper_bound (default 0.5/2.0). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use venv-split install pattern in submit_eval_jobs.py to preserve image's pre-baked torch/nvidia. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Ignore olmo-eval-internal/ checkout. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Replace submit_eval_jobs.py with shell wrapper around olmo-eval beaker launch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restore submit_eval_jobs.py as a thin translator over submit_eval_jobs.sh. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make rho_weights required in compute_grpo_loss; ones tensor disables correction. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CHANGELOG entry for #1650. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Even more narrow IcePop * Even more narrow IcePop * Add icepop_sequence_level flag for DeepSeek-V3.2 style sequence-level IcePop. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop submit_eval_jobs.{py,sh} changes; moved to PR #1658. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop sp_leader_metrics change; moved to PR #1659. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Rename TIS/IcePop knobs to unified rho_correction interface (use_rho_correction, rho_clamp_*, rho_mask_*). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * revert icepop changes * Revert "revert icepop changes" This reverts commit 155012c. * Revert non-rename changes in qwen3_4b_dapo_math.sh Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Restore rho_clamp_upper_bound default of 2.0 to match prior truncated_importance_sampling_ratio_cap default Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop redundant --rho_clamp_upper_bound 2.0 from scripts (matches default) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Default use_rho_correction=True to preserve prior TIS-on-by-default behavior; drop redundant --use_rho_correction flags from scripts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Restore 🤡 to resample warnings; use self.training_step in DataPreparationActor.run. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CHANGELOG entry for #1663. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update open_instruct/data_loader.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update open_instruct/data_loader.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
… Claude Opus 4.7 <noreply@anthropic.com> (#1665)
…1666) * Make mason.py --output_dir/--checkpoint_state_dir overrides idempotent; add grpo.py to OPEN_INSTRUCT_COMMANDS Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address PR #1666 review: fix replace_or_append_flag adjacent-flag bug; wire OLMo-core checkpointing into grpo.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make build_command_without_args flag-aware; simplify replace_or_append_flag to delegate Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop replace_or_append_flag; inline build_command_without_args + extend at call sites Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add test for repeated occurrences of value-bearing flag in build_command_without_args Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add grpo_checkpoint_integration_test.sh: two-pass resume verification for grpo.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix DataPreparationActorCheckpointCallback to call set_state instead of nonexistent restore_state Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr
…hored-By: Claude Opus 4.7 <noreply@anthropic.com> (#1685) Co-authored-by: Kevin Farhat <kevinfarhat@allenai.org>
* Use processed vLLM logprobs for GRPO * Match vLLM logprobs mode type hint * Add changelog for vLLM logprobs fix * Hardcode processed vLLM logprobs mode
* Emit per-Group generation times and rename trainer-idle metric Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop redundant time/getting_response; consumers read time/group_generation_max Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Rename generation_idle_waiting_for_trainer to generation_waiting_for_trainer Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Move maybe_evaluate to grpo_utils; dedupe calculate_token_counts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Retarget maybe_evaluate test mocks to grpo_utils Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Bump vllm to >=0.19.1 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Bump vllm 0.20.2, torch 2.11, CUDA 13.0; drop transformers override Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use cu128 wheels (Beaker driver is 12.8, can't run cu130) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Pin torchvision/torchaudio to cu128/cu130 wheels so ABI matches torch Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Revert torch/cu130/vllm 0.20 changes; stay on vllm 0.19.1 (Beaker driver too old for cu130) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Pass doc_lens/max_doc_lens to OLMo-core in forward_for_logprobs; bump olmo-core Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update CHANGELOG with PR #1670 link Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * now we use olmo-core at head * Fix doc_lens padding bug and vectorize max_doc_lens in compute_olmo_core_doc_lens Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Simplify compute_olmo_core_doc_lens: drop defensive guards and trim docstrings Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Document compute_olmo_core_doc_lens attention_mask format Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Use Shazeer shape suffixes in compute_olmo_core_doc_lens Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Assert flash attention backend in GRPOTrainModule for doc_lens path Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Apply doc_lens/max_doc_lens packing fix to DPO and consolidate helpers in olmo_core_utils Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Inline concatenated_input_ids accesses in concatenated_forward_olmo Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Remove references to deleted ppo_vllm_thread_ray_gtrl.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Address PR review: remove dead update_command_args.py refs, fix RLVR quickstart Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Verify HF export at startup; rewrite save_state_dict_as_hf via convert_state_to_hf; prune permanent checkpoints Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update CHANGELOG with PR #1671 link Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr * Bump olmo-core to f1b69d79; drop _register_pre_norm_olmo_core_to_hf_overrides shim now that upstream handles llama/qwen3/gemma3 norm mappings Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop unused model_config arg from save_state_dict_as_hf and redundant config save (PR #1671 review) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add type annotations to export_to_hf in dpo.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Inline get_hf_config helper in olmo_core_utils.py Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Annotate save_state_dict_as_hf and switch verify_can_save_as_hf log to f-string Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add trailing newline to olmo_core_utils.py to fix style-check * Make model_name_or_path required on ModelConfig and drop redundant None guards Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Trim CHANGELOG entry for #1671 to reflect what actually shipped Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Make olmo_core_utils.ModelConfig kw_only to fix DPOExperimentConfig field ordering Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Move maybe_evaluate to grpo_utils; dedupe calculate_token_counts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Verify HF export at startup; rewrite save_state_dict_as_hf via convert_state_to_hf; prune permanent checkpoints Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update CHANGELOG with PR #1671 link Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * GRPO OLMo-core feature parity: EvalCallback, setup_eval, checkpointer, scheduler types Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Update CHANGELOG with PR #1672 link Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop pre-norm Qwen3/Llama OLMo-core->HF override shim; upstream olmo-core now provides these mappings Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Minimize diff: drop PruningCheckpointerCallback, ty:ignore, and unrelated script tweaks Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Unify checkpoint_state_freq disable sentinel: <=0 disables on both grpo_fast and olmo_core paths Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Update grpo_callbacks.py * Use keyword args in EvalCallback.post_step's maybe_evaluate call Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Move save_freq/checkpoint_state_freq divergence warning into GRPOExperimentConfig.__post_init__ Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
* simplify clipfrac * Add clipfrac changelog entry * Apply clipfrac review suggestions
* Export setuptools-scm pretend version in debug launch scripts. Ray debug runs need a fixed open-instruct package version when the checkout is not a full git repo; set SETUPTOOLS_SCM_PRETEND_VERSION_FOR_OPEN_INSTRUCT=0.0.0+debug in all scripts/train/debug/**/*.sh. Co-authored-by: Cursor <cursoragent@cursor.com> * Add PR link to CHANGELOG entry. Co-authored-by: Cursor <cursoragent@cursor.com> * Limit setuptools-scm pretend version to local Ray debug scripts. Only grpo.sh and grpo_fast.sh set TORCH_COMPILE_DISABLE=1; remove the export from the other debug launch scripts added in error. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
* tv divergence * correct citation for importance sampling between vllm and trainer * fix rho_sequence_level to sequence_level_mean helper func and fix tv divergence stuff * fix docstring * fix tests * tv divergence masking * fix docstring * style and changelog
* Expand ty type-checking coverage and fix type errors. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * cleaned up pr * Move CodeRequest/CodeResponse above _run_user_code to drop forward reference. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Replace ty: ignore directives with typed casts. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix docstrings for validate_placeholders and verify_bullet_points to match new bool return type. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * more changes * Revert sample_logits_vllm.py parser casts to match repo convention. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CHANGELOG entry for type-checking expansion. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Use fp32 RoPE for Qwen3 OLMo-core configs and log GRPO metrics every step (https://github.com/allenai/open-instruct/pull/0). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Bump OLMo-core to finbarr/tie-lm for tied Qwen3 word embeddings (https://github.com/allenai/open-instruct/pull/0). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Keep _metrics non-empty per step in GRPO OLMo-core to avoid bookkeeping PG deadlock; switch dapo_math_oc eval datasets to allenai/ Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Rename GRPO keepalive metric so it doesn't collide with training_step Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop --budget flag from qwen3_4b_dapo_math.sh Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Add CHANGELOG entry for PR #1708 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop qwen rope_full_precision override to match HF Qwen3 (bf16 rotation, fp32 cos/sin) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Michael <noukhovm@mila.quebec>
…1715) * Minimal Olmo Hybrid DPO support for dpo.py: bump OLMo-core (olmo3_hybrid_7B preset + HF conversion), fla 0.5.0 + tilelang, selected_modules AC with checkpoint_wrapper determinism patch, GDN-aware ModelDims, olmo-core DPO sweep script Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Simplify: co-locate determinism patch in build_ac_config, forward AC mode/modules at SFT/GRPO call sites, add ModelDims.num_softmax_attn_layers Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add budget-AC variant of olmo-core hybrid DPO sweep script to test budget checkpointing with fla tilelang backend Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Remove unsupported 'full' activation checkpointing mode; only 'budget' and 'selected_modules' remain Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Replace checkpoint_wrapper determinism-check monkeypatch with upstream OLMo-core config: bump ai2-olmo-core rev to 76c239ca (adds configurable determinism_check), forward determinism_check='none' via build_ac_config selected_modules path Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Delete scripts/train/olmo-hybrid/7b_instruct_dpo_sweep_olmo_core.sh * Add PR link to Olmo Hybrid DPO CHANGELOG entry to satisfy CHANGELOG CI check Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Fix: detect_attn_implementation for flash-attn-2 * Lint
* Fix flaky code API test server startup * Add changelog entry for API test flake fix * Use backoff for API test server startup * Use contextlib for API test server * Simplify API test server: fold lifecycle back into class, drop try/except Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Reduce API test port flakiness
Register MiniMax-M3 in PRICE_PER_MILLION_TOKENS for cost tracking. M3 is the new flagship MiniMax model. Pricing matches MiniMax-m2.7-highspeed ($0.6 per 1M input tokens, $2.4 per 1M output tokens). The context_window_checker substring match on 'minimax' already covers M3 without further changes. Co-authored-by: octo-patch <octo-patch@github.com>
* Refactor OLMo-core DPO metrics: defer token-weighted reduction to DPOMetricsCallback, align wandb keys, add padding_fraction/sequences_per_step Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Use str.removeprefix in DPOMetricsCallback metric reconstruction Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * DPO metrics: record step/epoch/LR in train module; avoid per-step sync in get_num_sequences Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Use module-import style for olmo_core_train_modules in dpo.py; drop dead avg_sequence_length guard Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Rename perf/tokens_per_second_total back to perf/tokens_per_second_avg Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Rename perf/tokens_per_second_total to perf/tokens_per_second_avg in dpo_tune_cache.py Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * DPO: divide sequences_per_step by TP/CP duplication factor so it isn't overcounted under tensor parallelism Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * DPO: use ReduceType.mean for sequences_per_step so TP/CP duplicate ranks aren't double-counted Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * DPO: rename sequences_per_step to sequences_per_rank and add global_sequences_per_step total Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * DPO: remove DPOMetricsCallback, reduce token-weighted metrics inline like GRPO Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ude Opus 4.8 <noreply@anthropic.com> (#1722) Co-authored-by: Michael <noukhovm@mila.quebec>
* Bump OLMo-core to latest main commit Update the `ai2-olmo-core` git rev from `76c239ca` to the latest main commit `9aa3280f` and refresh `uv.lock`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add CHANGELOG entry for OLMo-core bump --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Change default temperature to 1.0 Set StreamingConfig.temperature default to 1.0 and make SamplingConfig.temperature a required field so StreamingConfig is the single source of truth for the default generation temperature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Update CHANGELOG with PR number Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ar) on ModelConfig (#1714) * Expose olmo-core's lm_head loss_implementation (e.g. Liger fused_linear) on ModelConfig * Add CHANGELOG entry for #1714 * Default loss_implementation to LMLossImplementation.default Avoids handling None as a special case, per Finbarr's review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Fix CHANGELOG: keep only the #1714 entry Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Michael Noukhovitch <michaeln@allenai.org> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request integrates OLMo-core's training infrastructure into the repository, adding a native SFT training script (olmo_core_finetune.py) and a dataset conversion utility (numpy_dataset_conversion.py) to prepare SFT datasets in numpy mmap format. It also refactors the DPO and GRPO trainers to align with OLMo-core utilities, introduces a unified ρ correction (train/infer ratio correction) in GRPO, updates evaluation scripts, and bumps dependencies. The review feedback identifies several key issues: guarding Ray actor calls in perform_weight_sync with is_rank_0 to prevent redundant RPC overhead, correcting a 0-based step indexing off-by-one error in EvalCallback, defensively handling numeric types in parse_dataset_mixer_list to avoid TypeError, and guarding logprob indexing in process_group to prevent potential IndexError crashes.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| start = time.perf_counter() | ||
| ray.get(actor_manager.set_should_stop.remote(True)) | ||
| try: | ||
| results, actor_sync_times = utils.ray_get_with_progress( | ||
| broadcast_refs, desc="Broadcasting weights to vLLM engines", enable=progress | ||
| ) | ||
| if not inflight_updates: | ||
| utils.ray_get_with_progress( | ||
| itertools.chain.from_iterable(results), desc="Waiting for vLLM engine update RPCs", enable=progress | ||
| ) | ||
| utils.ray_get_with_progress( | ||
| [e.wake_up.remote() for e in vllm_engines], desc="Waking up vLLM engines", enable=progress | ||
| ) | ||
| finally: | ||
| ray.get(actor_manager.set_should_stop.remote(False)) |
There was a problem hiding this comment.
In distributed training, perform_weight_sync is called on all ranks. However, Ray actor calls (such as pausing the actor manager and waking up the vLLM engines) are external, non-collective operations that should only be coordinated by rank 0. Having all ranks concurrently invoke these remote methods leads to massive redundant RPC overhead and potential bottlenecks/deadlocks. Guarding these calls with is_rank_0 ensures that only the main process interacts with the Ray actors.
| start = time.perf_counter() | |
| ray.get(actor_manager.set_should_stop.remote(True)) | |
| try: | |
| results, actor_sync_times = utils.ray_get_with_progress( | |
| broadcast_refs, desc="Broadcasting weights to vLLM engines", enable=progress | |
| ) | |
| if not inflight_updates: | |
| utils.ray_get_with_progress( | |
| itertools.chain.from_iterable(results), desc="Waiting for vLLM engine update RPCs", enable=progress | |
| ) | |
| utils.ray_get_with_progress( | |
| [e.wake_up.remote() for e in vllm_engines], desc="Waking up vLLM engines", enable=progress | |
| ) | |
| finally: | |
| ray.get(actor_manager.set_should_stop.remote(False)) | |
| start = time.perf_counter() | |
| is_rank_0 = not dist.is_initialized() or dist.get_rank() == 0 | |
| if not is_rank_0: | |
| return {"time/weight_sync": 0.0}, [] | |
| ray.get(actor_manager.set_should_stop.remote(True)) | |
| try: | |
| results, actor_sync_times = utils.ray_get_with_progress( | |
| broadcast_refs, desc="Broadcasting weights to vLLM engines", enable=progress | |
| ) | |
| if not inflight_updates: | |
| utils.ray_get_with_progress( | |
| itertools.chain.from_iterable(results), desc="Waiting for vLLM engine update RPCs", enable=progress | |
| ) | |
| utils.ray_get_with_progress( | |
| [e.wake_up.remote() for e in vllm_engines], desc="Waking up vLLM engines", enable=progress | |
| ) | |
| finally: | |
| ray.get(actor_manager.set_should_stop.remote(False)) |
| if not ( | ||
| (self.args.eval_on_step_0 and self.trainer.global_step == 1) | ||
| or (self.trainer.global_step % self.args.local_eval_every == 0 and self.trainer.global_step > 1) | ||
| ): |
There was a problem hiding this comment.
In olmo_core, the trainer's global_step is 0-based, meaning the very first step of training is step 0. Checking self.trainer.global_step == 1 for eval_on_step_0 will cause the initial evaluation to run at step 1 instead of step 0 (or not run at all if step 0 is skipped). Updating the conditions to check for global_step == 0 and global_step > 0 ensures that the initial evaluation runs correctly at the start of training.
| if not ( | |
| (self.args.eval_on_step_0 and self.trainer.global_step == 1) | |
| or (self.trainer.global_step % self.args.local_eval_every == 0 and self.trainer.global_step > 1) | |
| ): | |
| if not ( | |
| (self.args.eval_on_step_0 and self.trainer.global_step == 0) | |
| or (self.trainer.global_step % self.args.local_eval_every == 0 and self.trainer.global_step > 0) | |
| ): |
| i = 0 | ||
| while i < len(mixer_list) - 1: | ||
| assert isinstance(mixer_list[i], str), f"Invalid type in data mixer: {mixer_list}" | ||
| value = float(mixer_list[i + 1]) if "." in mixer_list[i + 1] else int(mixer_list[i + 1]) |
There was a problem hiding this comment.
If mixer_list is passed programmatically and already contains numeric types (such as float or int), performing "." in mixer_list[i + 1] will raise a TypeError because numbers are not iterable. Coercing or checking the type defensively prevents runtime crashes when the list is not entirely composed of strings.
| value = float(mixer_list[i + 1]) if "." in mixer_list[i + 1] else int(mixer_list[i + 1]) | |
| raw_val = mixer_list[i + 1] | |
| if isinstance(raw_val, (int, float)): | |
| value = raw_val | |
| else: | |
| value = float(raw_val) if "." in raw_val else int(raw_val) |
| for i in range(len(result.finish_reasons)): | ||
| if result.finish_reasons[i] == "stop" and len(result.responses[i]) == 0: | ||
| result.responses[i].append(tokenizer.eos_token_id) | ||
| result.masks[i].append(1) | ||
| result.logprobs[i].append(float("nan")) |
There was a problem hiding this comment.
If logprobs are not requested or not populated, result.logprobs may be empty, causing result.logprobs[i] to raise an IndexError. Adding a guard to check if i < len(result.logprobs) prevents potential runtime crashes when logprobs are disabled.
| for i in range(len(result.finish_reasons)): | |
| if result.finish_reasons[i] == "stop" and len(result.responses[i]) == 0: | |
| result.responses[i].append(tokenizer.eos_token_id) | |
| result.masks[i].append(1) | |
| result.logprobs[i].append(float("nan")) | |
| for i in range(len(result.finish_reasons)): | |
| if result.finish_reasons[i] == "stop" and len(result.responses[i]) == 0: | |
| result.responses[i].append(tokenizer.eos_token_id) | |
| result.masks[i].append(1) | |
| if i < len(result.logprobs): | |
| result.logprobs[i].append(float("nan")) |
* Increase default environment pool acquire timeout to 7200s Bump DEFAULT_ACQUIRE_TIMEOUT_S so long-running sandbox rollouts don't spuriously time out while waiting to acquire an actor. Co-authored-by: Cursor <cursoragent@cursor.com> * Add changelog entry for pool acquire timeout increase Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
* Drop stale async rollout results Add max_result_age_steps to accumulate_inference_batches: rollouts whose generating policy is more than that many steps behind the trainer are dropped (and a fresh prompt is replenished) rather than trained on, with a stale_results_dropped metric. Wired from the DataPreparationActor using async_steps as the threshold. Adds a result_is_stale helper + unit tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Add CHANGELOG entry for stale rollout dropping (#1738) Co-authored-by: Cursor <cursoragent@cursor.com> * Log per-batch count of dropped stale rollout results Co-authored-by: Cursor <cursoragent@cursor.com> * Require replenish_prompts when staleness dropping is enabled Dropping stale results without replenishing would steadily drain the in-flight prompt pool and hang the accumulator, so validate up front that max_result_age_steps is only used with replenish_prompts=True. The drop path now replenishes unconditionally. Adds a unit test for the guard. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
* Upgrade to CUDA 13.0 for B300 support on ai2/holmes - Base Docker image: nvidia/cuda:12.8.1 -> 13.0.3-devel-ubuntu22.04 - torch/torchvision/torchaudio from the cu130 index on all Linux (torchvision/torchaudio added as direct deps so the index pin applies) - vllm from wheels.vllm.ai +cu130 builds (PyPI wheels are cu128) - flash-attn and flash-attn-3 switched to cu130 wheels - Add B300 entry to GPU_SPECS (288GB HBM3e) with tests - Add ai2/holmes to WEKA_CLUSTERS and INTERCONNECT_CLUSTERS Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Remove outdated generation golden and point GPU tests at ai2/holmes The without-tools determinism golden was generated with the cu128 vLLM build; greedy decode diverges with the cu130 build on B300 (39/40 GPU tests passed on holmes, this was the only failure). Following the documented regeneration workflow in test_grpo_fast_gpu.py. run_gpu_pytest.sh now targets ai2/holmes only: the CUDA 13 image needs driver >= 580, and jupiter/ceres/saturn drivers are too old (verified: saturn fails with "driver too old (found version 12080)"). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add regenerated generation golden from B300/cu130 run Generated by experiment 01KXHZ2M7YE3S7QNPC3DZWZ0GD on ai2/holmes, fetched from its result dataset per the documented workflow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add changelog entry for PR 1758 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Support selectable CUDA 12 and 13 images * Isolate image launcher environment * Expose CUDA variant in GPU test runs * Detect CUDA version from PyTorch at runtime * Parse PyTorch CUDA version robustly * Route GPU tests from image CUDA variant * Isolate Mason with minimal dependencies * Revert "Isolate Mason with minimal dependencies" This reverts commit e45444b. * Revert "Isolate image launcher environment" This reverts commit c5c74b2. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Wire max_checkpoints through all OLMo-core training paths Pass the existing keep_last_n_checkpoints config (default=3) to CheckpointerCallback's new max_checkpoints parameter across SFT, DPO, and GRPO training paths. Also adds keep_last_n_checkpoints to GRPOExperimentConfig (it was missing, unlike the SFT/DPO configs). Depends on allenai/OLMo-core#timd/add-max-checkpoints which adds the max_checkpoints parameter to CheckpointerCallback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Address review feedback: centralize -1→None mapping, remove duplicate field - Move -1 to None conversion into build_checkpointer_callback - Remove redundant keep_last_n_checkpoints from GRPOExperimentConfig (inherited from CheckpointConfig) - Simplify all call sites to pass value directly - Add CHANGELOG entry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Bump OLMo-core pin to fa6c5014 (adds max_checkpoints) The previous pin predates OLMo-core#694, which adds the max_checkpoints parameter this PR wires through. Regenerate uv.lock/requirements.txt to match. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Michael Noukhovitch <michaeln@allenai.org>
No description provided.