Repository navigation
[RFC]: Training support and verl/vime integration for looped-transformer inference optimization #70
Description
Progress update — 2026-10-22
Baseline: main 4a350344027960a48384626aa646f1765fda6d4f.
- [FEAT] Rollout outputs: selected-token logprobs, effective seeds and stop token IDs (part of #70) #83 remains open for selected-token logprobs, effective seeds and custom stop IDs. Its latest description includes the speculative-runner scoring contribution; the GPU suite has not been rerun on that combined head.
- Expose rollout logprobs and full policy publication on shared engines #78 remains open for rollout scores and transactional full-weight publication. Its broader real-model/PD/training evidence is historical and must not be transferred automatically to a rebased implementation.
- Interface/order decision remains open: the coordination question asks whether to land [FEAT] Rollout outputs: selected-token logprobs, effective seeds and stop token IDs (part of #70) #83 then publication, or use Expose rollout logprobs and full policy publication on shared engines #78 as the integration base. This refresh does not select either route or assign duplicate implementation work.
- [Architecture] Unify stage execution with loop-level scheduling and mixed batching #118/[Refactor] Move runner result application to Scheduler (M2/R1) #107 changed the engine/stage and result-application boundaries. Integrate the selected training contract through those current interfaces, then revalidate output/depth/score alignment, publication versions, prefix invalidation and failure recovery.
- [Feature] Add experimental deferred Ouro deep batching #125 is a separate draft mixed-readout deferred-deep experiment. Its CPU tests do not complete rollout/weight publication, learner replay or real-weight BF16 performance qualification.
- Token-facing serving/control work and end-to-end framework replay remain separate acceptance items; no complete training integration is marked merged here.
Existing contributor scopes and external adapter work are retained below.
Motivation.
Enable training-driven improvements to vllm-rlt's looped-transformer inference efficiency. Optimize throughput, latency, and memory use under an explicit quality constraint.
Looped transformers provide specific opportunities: predict exits ahead of execution, align shallow draft predictions with deeper target computation, and make better use of recurrent state and shared weights. Exploring these ideas requires reliable rollout and weight-update interfaces before integrating a training framework.
The proposed order is:
- Add framework-independent training support to vllm-rlt through repository PRs.
- Integrate and run training loops on contributor forks of verl/vime.
- Use those forks to train and evaluate loop-specific inference optimizations; upstream useful engine capabilities with evidence.
Proposed Change.
Scope, ownership, and progress
Initial integration target: Ouro-1.4B, BF16, synchronous training iterations, and full weight updates. Training interfaces and framework adapters must preserve existing inference features, including early exit, PD, speculative decoding, and CUDA Graphs, from the start. Do not impose a fixed-depth, single-device, non-speculative restriction on the integration. Raise concrete compatibility issues for discussion; this requirement does not imply that currently unsupported feature combinations are already implemented. Asynchronous training, incremental weight transfer, and colocated training/inference memory switching remain separate extensions.
Start with verl + FSDP as the proposed first integration; add vime with its training stack through a second adapter. Pin framework versions and validate model compatibility in the integration itself. Train/inference consistency and gradient checks are required integration tests.
- ✅ Completed for the stated scope.
- 🚧 Claimed or in progress, with a linked claim, PR, or fork branch; not yet accepted as complete.
- ⬜ Not yet delivered in this tracker; existing components should be reused where applicable.
Contributors may split tasks or collaborate. Record Assignee(s), engine PRs, and fork branch/results links. Phase 1 is a joint development scope for @MinhaoLi0318 and @IDEA-V, coordinated with @0z5a and @Levius-Fubuki on the shared interfaces. @Levius-Fubuki has confirmed ownership of N+2 exit optimization, including predictor training and runtime integration, planned after establishing the verl/FSDP loop; implementation has not yet been reported as started. @IDEA-V has confirmed participation in Phase 1. @CXJorz is onboarding and has no implementation task assigned yet.
| Phase | Deliverable | Code destination | Status | Assignee(s) | PR / branch / evidence |
|---|---|---|---|---|---|
| 1 | Training-facing engine capabilities | vllm-rlt PRs | 🚧 | @MinhaoLi0318, @IDEA-V | Plan, co-author coordination |
| 2A | Ouro training integration with verl/FSDP | Contributor verl fork | 🚧 | @Levius-Fubuki | Claim |
| 2B | Equivalent integration with vime | Contributor vime fork | 🚧 | @0z5a | vime prototype, engine prototype |
| 3 | Loop-specific exit and speculative training experiments | Framework forks; experimental engine branches as needed | 🚧 | @IDEA-V (speculation); @Levius-Fubuki (exit, confirmed; planned after 2A) | Claim, Ownership confirmation |
Implementation references
Reference vLLM's rollout and weight-synchronization implementation, and adapt verl/vime's existing vLLM integrations. Preserve recurrent shared-weight and depth-aware KV semantics, documenting necessary differences and the referenced versions.
- vLLM weight transfer and source.
- verl vLLM rollout and extension interfaces.
- vime, customization, and model adaptation.
Implementation details, experiment procedures, training methods and PR boundaries are left to contributors. The requirements below define the deliverables and acceptance criteria.
Phase 1: training-facing capabilities in vllm-rlt
Provide a shared engine contract based on the relevant vLLM interfaces, usable by both frameworks without adding verl/vime dependencies to normal inference installation. Prefer compatible field and operation names; document required deviations in the implementation PRs.
| Task | Scope and acceptance | Status | Assignee(s) | PR / plan |
|---|---|---|---|---|
| Training rollout interface | Token-ID input/output, selected-token logprobs, effective sampling configuration, concurrent requests and request lifecycle. Preserve token alignment and termination reasons; support cancellation/error cleanup; document model-versus-sampling probability conventions. | 🚧 | @MinhaoLi0318, @IDEA-V | Plan, co-author coordination |
| Weight update and synchronization | Support reliable full-weight updates with model-version tracking and correct cache/state handling. Generation must use a consistent weight version, and update failures must be reported safely. | 🚧 | @MinhaoLi0318, @IDEA-V | Plan, co-author coordination |
Acceptance requires correct token/probability alignment, concurrent request handling, and consistent generation after weight updates. Document probability conventions, preserve recurrent weight sharing, and prevent reuse of incompatible cached state. Keep the interfaces framework-independent and include relevant correctness and overhead measurements.
The agreed Phase 1 delivery is split into three PRs: rollout outputs; full-weight update and synchronization; and concurrent token-in/token-out API with abort/pause. Build on vLLM and @0z5a’s existing prototype, with shared development and appropriate co-author credit. Existing inference-feature compatibility is part of this delivery, not a later phase.
Phase 2: integration on verl/vime forks
After the engine contract is usable, adapt each framework’s existing vLLM integration to vllm-rlt and run end-to-end experiments on contributor forks. Upstream PRs to verl or vime are not required to complete this phase. Missing generic engine capabilities should be proposed back to vllm-rlt rather than maintained as two incompatible private interfaces.
| Task | Scope and acceptance | Status | Assignee(s) | Branch / evidence |
|---|---|---|---|---|
| verl/FSDP integration | Adapt Ouro training and the vllm-rlt rollout backend, map/export shared recurrent weights, coordinate updates, and provide a reproducible multi-iteration training recipe with consistency and save/resume checks. | 🚧 | @Levius-Fubuki | Claim |
| vime integration | Adapt Ouro to the training stack and reuse the engine rollout/update contract; provide parameter conversion and a reproducible multi-iteration recipe with consistency and save/resume checks. | 🚧 | @0z5a | vime prototype, engine prototype |
Provide a reproducible end-to-end training run that verifies correct gradients, weight updates, synchronization, and generation with the updated model. Include train/inference probability consistency and checkpoint recovery evidence. Link the runnable fork branch, configuration and results.
Phase 3: loop-specific training experiments for inference efficiency
Use the integrated training environment to optimize recurrent execution.
| Task | Scope and acceptance | Status | Assignee(s) | Branch / results |
|---|---|---|---|---|
| Lookahead exit optimization | Train and deploy the N+2 exit predictor, including data/labels, checkpoint loading and runtime decisions. Evaluate task quality, selected versus executed depth, and low/high-concurrency throughput and latency. | ⬜ | @Levius-Fubuki (confirmed; planned after 2A) | Ownership confirmation |
| Loop-aware speculative optimization | Train shallow draft heads/adapters or depth-specific fine-tuning, integrate the resulting draft path, and evaluate quality, acceptance lengths, computation reuse, memory and end-to-end speedup. | 🚧 | @IDEA-V | Claim |
Experiment goals and acceptance
- N+2 exit: use information available at round N to predict whether the token can exit at round N+2; execute through N+2 and use that round's hidden state for output. Preserve valid exit/KV semantics and evaluate quality, selected versus actual executed depth, and throughput/latency against relevant existing baselines.
- Loop-aware speculation: improve shallow drafting while preserving valid target verification and identifying reusable recurrent computation. Evaluate output quality, acceptance lengths, extra computation/memory and end-to-end performance against target-only and current speculative inference.
Training architecture, labels, losses, datasets and experimental procedures are chosen by contributors and documented with results. Add reusable trace collection, trained-component loading or other engine support as required by the experiment. Adaptive training/rollout must preserve consistent trajectory and KV semantics.
Code location and PR scope
| Code / artifact | Destination |
|---|---|
| Generic rollout, probability, versioning and update interfaces | vllm-rlt PRs |
| Framework adapters, differentiable model adaptation, weight conversion and training configuration | Contributor verl/vime forks initially |
| Labels, losses, training scripts and experimental results | Framework forks / linked experiment artifacts |
| Experimental exit/draft execution changes | Linked engine experiment branches, paired with framework forks |
| Useful trace collection or trained-component loading | vllm-rlt PRs after validating the shared requirement |
| New runtime exit/speculation policy | vllm-rlt PR with correctness, quality and performance evidence |
Negative or inconclusive experiments should retain results without requiring a production runtime merge. Keep framework-specific dependencies outside the normal inference installation. Update README/relevant docs for new public engine capabilities and supply reproducible integration/experiment instructions.
Alternatives and impact
Use a shared engine contract for both framework adapters to avoid duplicating rollout and weight-update protocols. Keep framework dependencies in the fork integrations.
Implementation PRs must document API changes, probability-collection overhead, update downtime, memory use and state lifecycle behavior. Experimental heads and policies are opt-in; performance evaluation must include matched quality measurements.
Feedback Period.
At least one week after publication of this draft. Keep the issue open as a living implementation and experiment tracker.
CC List.
Anything else.
Related work: #69 for model/backend/runtime support; #56 for adaptive-exit evaluation and execution semantics; #43 for speculative inference.
Training frameworks: verl and vime.
Before submitting a new issue...
- Make sure you already searched for relevant issues in the issue tracker, and looked for the answer in the documentation.
Activity
[-][RFC]: Recipe tracking for correctness, quality, and performance across GPU and NPU[/-][+][RFC]: Training support and verl/vime integration for looped-transformer inference optimization[/+]0z5a commentedon Sep 29, 2026
I've tried combination of vllm-rlt and Vime on GRPO rollout with few steps reward(0z5a/vime#4 and 0z5a#1). I would be glad to take further combination work of Vime integration.
Levius-Fubuki commentedon Sep 29, 2026
Hi @bjf-frz @hsliuustc0106, I'd like to take ownership of Phase 2A: Ouro training integration with verl/FSDP, and develop it into a reusable training–rollout path.
My related contributions include merged Triton attention optimization in vLLM, MoE-LoRA computation and routing optimizations in VeOmni, and shared diffusion runtime integration. I also have an open DSpark training-loss optimization PR in Vime.
For the first delivery, I'll follow the RFC's Ouro-1.4B/BF16, fixed four-loop, synchronous-iteration scope, with a standalone non-speculative single-device rollout instance and full weight updates. The implementation would cover:
@0z5a, I saw your Vime integration and engine prototype. I'd like to coordinate on and reuse the common rollout/weight-publication contract, contributing missing framework-independent capabilities back to vllm-rlt rather than creating a separate verl-specific engine interface. My primary ownership request is Phase 2A.
Once that loop works, I'd also like to pursue Phase 3's trained N+2 lookahead exit predictor as the follow-on direction: training and component loading through runtime exit decisions, coordinated with the existing exit-policy work. This would use round-N information to predict an exit at N+2, actually execute through N+2, and use that round's hidden state for output; any runtime proposal would include quality and end-to-end performance evidence.
I'll start by pinning the framework versions, mapping the shared-parameter and engine interfaces, and implementing the first fixed-depth adapter increment. Please record me for Phase 2A if this scope fits; happy to coordinate the shared Phase 1 boundaries and subsequent N+2 work.
CXJorz commentedon Sep 29, 2026
I'm new to infra, but I also want to make some contributions to the community
IDEA-V commentedon Sep 29, 2026
I’d like to take on the loop-aware speculative optimization task in Phase 3. It aligns closely with my ongoing work on intermediate predictions across loops and speculative execution.
I’m happy to own the experiments and runtime integration for this task, and coordinate with the Phase 1/2 contributors on the required interfaces. Please put me down for this part!
MinhaoLi0318 commentedon Sep 29, 2026
Hi @bjf-frz @hsliuustc0106, I'd like to take Phase 1: training-facing engine capabilities, covering both the training rollout interface and weight update/synchronization, so that 2A (@Levius-Fubuki), 2B (@0z5a) and the Phase 3 items can build on one shared contract.
Background: I own the adaptive-depth rows in #69 (#56, with the harness merged in #58). On the vLLM side I've worked on RL rollout integration, for example Tencent-Hunyuan/UniRL rollout through vLLM-Omni and vllm-project/vllm-omni#8196.
@0z5a, your RLEngine prototype (0z5a#1) already has the minimal shape. I'd build on its semantics in the core
LLMEngine/LLMpath and credit it, so your vime adapter can use the upstream contract. If you'd rather upstream part of it yourself, I'm happy to split the work.Proposed PRs. They use vLLM-compatible names, and each reports overhead, update downtime and memory, as the RFC asks.
token_ids;logprobs_moderaw by default, as in vLLM, with processed also supported because verl and vime request it;seed=Noneandstop_token_ids;RequestOutput;start_weight_update/update_weights/finish_weight_update/get_weight_version, plusreset_prefix_cache;Two things on main matter for RL. Both reproduce on the tiny CPU model at 9e3d13d, and both would get tests:
seed=0, identical prompts at T=1 sample identical outputs, so a GRPO group would get zero advantage.Questions:
seed: addseed=Noneas an opt-in, or change the default? [REFACT] [M7 1/3] Extract the sampling module and pin request-local RNG behavior #45 pinned the current seeded behavior.I can start once the scope fits. CPU tests will use the tiny model; GPU checks will run on an RTX 5090 with the Triton backend.
0z5a commentedon Sep 29, 2026
Sounds good.
bjf-frz commentedon Sep 29, 2026
Hi @MinhaoLi0318. I agree with splitting the work into the three PRs you proposed. The training interfaces do not inherently conflict with existing features such as early exit, PD, speculative decoding, and CUDA Graphs, so I suggest preserving support for them from the start rather than deferring compatibility to a later phase. Please refer to vLLM’s implementation and @0z5a’s existing work, and coordinate the shared interfaces with @0z5a and @Levius-Fubuki.
bjf-frz commentedon Sep 29, 2026
Hi @Levius-Fubuki, the plan looks good overall. As with Phase 1, I suggest making the verl integration work with existing inference features from the start, including early exit, PD, speculative decoding, and CUDA Graphs. Please refer to verl’s existing vLLM integration and coordinate the shared interfaces with @0z5a and @MinhaoLi0318.
bjf-frz commentedon Sep 29, 2026
Hi @IDEA-V, you could also collaborate on Phase 1 as a co-author with @MinhaoLi0318, coordinating the shared interfaces with @0z5a and @Levius-Fubuki. This should also help support your Phase 3 work on loop-aware speculative decoding.
Levius-Fubuki commentedon Sep 29, 2026
Thanks! I’ll coordinate with @0z5a and @MinhaoLi0318 and preserve existing inference-feature support from the start. I also confirm my intention to own N+2 exit optimization, including predictor training and runtime integration, after establishing the verl/FSDP loop.
IDEA-V commentedon Sep 29, 2026
Sure. I'm happy to participate.
MinhaoLi0318 commentedon Oct 1, 2026
Following the developer guide (#75), here is the design for PR 1 (rollout outputs), written against main
ecb1f8b, before I start coding. @IDEA-V @0z5a @Levius-Fubuki, please point out anything your adapters need that is missing.Contract (vLLM names; deviations marked)
SamplingParams.logprobs: int | None = None.0returns the selected token only, which is what verl and vime request. Values above0(top-k alternatives) are rejected for now.SamplingParams.seed: int | None = 0. WithNone,add_requestdraws a per-request seed and reports it, so a rollout can be replayed exactly. The default stays0, as pinned by [REFACT] [M7 1/3] Extract the sampling module and pin request-local RNG behavior #45. vLLM defaults toNone; if you want that here, flipping the default can be a separate one-line PR.SamplingParams.stop_token_ids. EOS is currently checked in three places: sync coda, async coda delivery and speculative commit. One shared helper will check both EOS andstop_token_ids.logprobs_mode:raw_logprobs(the default, as in vLLM) orprocessed_logprobs. The logits modes are rejected.RequestOutputfields:logprobs: list[float] | None, aligned 1:1 withtoken_ids(and withexit_depths) for stop, length and abort. Deviation: flat floats rather than vLLM'slist[dict[int, Logprob]], since only the selected token is returned.sampling_params: the resolved parameters, including the effective seed.weight_versionmoves to PR 2, where versions actually exist.RLCompletionfields map ontoRequestOutputas follows.token_ids,exit_depthsandfinish_reasonkeep the same names.log_probsbecomeslogprobs.loop_budgetbecomessampling_params.min_loops/max_loops.policy_versionbecomesweight_version(PR 2). Its logprob,log_softmax(logits / T)[token], is exactlyprocessed_logprobswith no top-k/top-p. Differences from the prototype: the support is in the core engine rather than anRLEnginesubclass, and it doesn't add the subclass's restrictions (T>0 only, unfiltered sampling only, fixed depth, no prefix cache/async/spec).Probability convention (this goes into the docs)
log_softmax(coda(h_d))[token], whered = exit_depths[i]is the depth the token actually exited at.min_loops/max_loopsaffect decode tokens only.exit_depths. Underlast_exitedKV, it must also reproduce the copied deeper-loop KV. I'll report the measured mismatch on Ouro-1.4B rather than block PR 1 on it.Compatibility, all in this PR
test_greedy_matches_native_*. Sampled spec is exact in distribution, so log p_target is the right policy logprob.Requestlikeexit_depthsand travel in the existingoutputmessage. This gets a 2-GPU test.CodaGraphsare read before the next replay. Test: graphs on vs off.Overlap with #62: I'll put the "processed logits" step in one function shared by
Samplerand the speculativeprobabilities(). Whichever PR lands second adds its processors there, and processed logprobs then include repetition penalty and depth temperature automatically. cc @cs-ai-liValidation:
logprobs=Nonevs0(raw and processed) in sync, async and spec, plus ops-only and full profiles.@IDEA-V, would you take the speculative path: target-row logprobs plus the greedy-equality and sampled-replay tests, as co-authored commits on my branch? You know that runner from #51, and your Phase 3 work needs those target logprobs anyway. I'll do params, sampler, output, sync and async coda, PD, CUDA Graphs and the docs.
@0z5a, your
set_loop_budgetlowerstotal_ut_steps, so prefill also runs at the reduced depth. Does the vime pilot depend on reduced-depth prefill? If it does, I'd add that as an explicit engine option rather than a sampling parameter.0z5a commentedon Oct 1, 2026
@MinhaoLi0318 The current VIME pilot needs four-loop prompt prefill, so no reduced-prefill option is needed. VIME draft #5 supersedes the older
RLEngine.set_loop_budgetprototype with publicLLM.generate/ full-weight publication. Checkpointtotal_ut_stepsstays four; decode K usesSamplingParams.max_loops. The trainer replays[4] * prompt_length + exit_depths[1:] + [1](last input loss-masked), includinglast_exiteddeeper KV.I support your
RequestOutput.logprobsand engine-levelraw_logprobs/processed_logprobsnames, defaultseed=0, and opt-inseed=None. VIME uses processed scores. My reference draft #4 currently differs in output spelling (log_probs) and request-level mode (raw/processed); I will adapt the VIME consumer to your PR 1 when its branch is available, without introducing a duplicate compatibility API. The pilot's first consumer is in-processLLM; existing PD worker IPC can remain inside the engine.You and @IDEA-V can lead the proposed upstream Phase 1 output/stop/processor work. The companion draft provides tested reference code and full-publication checks reusable for PR 2; I am not claiming ownership of your Phase 1 PRs. These Thor checks test the proposal's semantics on the reference implementation, not your unpublished PR 1 code.
Your effective-seed requirement exposed a real omission: entropy sampling returned
seed=None. The minimal fix resolves/stores a 63-bit seed whenRequestis created, including abort before sampling. Seven CPU contract/PD-control tests, six CUDA contract tests and two VIME replay/gradient/conversion CPU tests pass. Exact token/score/depth replay covers ordinary, async and speculative paths, and preemption preserves scores/RNG; the unfixed seed regression fails as expected. Earlier full training/save/resume evidence retains exact 272 checkpoint tensors/Adam metadata and 269 export tensors.Full Ouro-1.4B now passes exact effective-seed token/score replay for K=2/3/4, early exit and delayed async, all with four-loop first-token prefill. Actual-depth recomputation reduces early-exit score MAE from 3.622689 (uniform four loops) to 0.011142. Residual differences remain: fixed K=4 also has MAE 0.026607, versus 0.025122 for uniform-four recomputation. Five-case error table and raw evidence.
Full-model selected-score time overhead vs
logprobs=None, raw/processed respectively: sync +1.46%/+1.47%, async +5.15%/+5.42%, spec +0.67%/+0.83%. Each mode has five rotated-order unprofiled repeats, plus separate ops-only/full-detail profiling (18 operator-summary windows). Markdown latency/throughput/allocation table and raw data. These observations include Qwen-Image training contention (initial GPU utilization 98%). Two UVM allocation waits resolved naturally; driver memory-allocation errors and stacks are retained. Initialization/capture and profiled windows are excluded from throughput medians. No processes were killed or environments/drivers changed.Please share the PR 1 branch/commit when ready so I can validate VIME against that exact revision. Effective seed, selected scores, physical exit trace and committed weight version remain the consumer requirements, with version publication landing separately in PR 2.
IDEA-V commentedon Oct 3, 2026
@MinhaoLi0318 Sounds good! I’m happy to take the speculative path. Please share your branch or draft PR when ready, and I’ll build on it.
MinhaoLi0318 commentedon Oct 3, 2026
@0z5a @IDEA-V Thanks both. PR 1 (rollout outputs) is up as draft #83 from
MinhaoLi0318/vllm-rlt:rl/rollout-outputsat57d2308, on mainecb1f8b. Everything except the speculative path is implemented. CPU tests pass; GPU validation and overhead measurements are next.@0z5a, that settles the open points: four-loop prefill stays, the names stay as proposed, and VIME reads processed scores. When you validate VIME against
57d2308:seed=Noneis resolved inadd_requestbefore theRequestexists, and also in the PD coordinator. An abort before the first sample therefore reports the int seed; there's a test for it.log_softmax(processed_logits)[token]rather thanlog(softmax(...)[token]). The values agree up to fp32 rounding, and very low-probability tokens stay finite instead of underflowing to-inf.[depth] * len(prompt) + exit_depths[1:], which matches your trainer.@IDEA-V, great, the speculative path is yours. To build on the branch, open PRs against
MinhaoLi0318/vllm-rlt:rl/rollout-outputs; I'll merge them so your commits land in #83 under your name. If you'd rather push to the branch directly, I can add you as a collaborator on the fork. What's already in place:SpeculativeResult.logprobsexists. The engine slices it together with the emitted tokens on EOS, stop IDs and length (LLMEngine._append_output).add_requestcurrently rejectslogprobswithspeculative_config. Your change lifts that rejection, andtest_admission_rejects_out_of_vocabulary_stop_ids_and_speculative_logprobsneeds the matching update.vllm_rlt.worker.sampling.token_logprob(row, params, token, mode)on the target verification row. Draws already go through the sharedprocessed_logits, so processed scores match what was sampled. 0z5a's reference (Expose rollout logprobs and full policy publication on shared engines 0z5a/vllm-rlt#4) already scores verification rows, which could save you time (with his credit).tests/test_speculative.py:398callsOuroConfig.tiny(...).OuroConfigisn't imported there (ruff F821), and notinyconstructor exists; the test helpers providetiny_ouro_config. So the test would fail on a GPU run.@bjf-frz, could you link #83 in the Phase 1 rows of the tracker?
MinhaoLi0318 commentedon Oct 6, 2026
Following the developer guide (#75), here is the design for PR 2 (full-weight update and synchronization), before I start coding. It is stacked on #83 (GPU-validated at
c5a7019, results in its description), since both addRequestOutputfields and touchpd/engine.py.It upstreams the publication contract of @0z5a's #78: the same methods and call order, the idle precondition, the prefix reset at start, and the PD broadcast. The changes are listed below. @0z5a @Levius-Fubuki @IDEA-V, please point out anything your adapters need. The full write-up will go into
docs/weight_update.md.Contract (vLLM names, identical on
LLM,LLMEngineandPDEngine; deviations in italics)start_weight_update(weight_version: int | None = None).startdiscards an open update. Their retry path relies on this.update_weights(weights: Iterable[tuple[str, Tensor]]), which may be called any number of times, so callers can send buckets.update_info.finish_weight_update(weight_version: int | None = None)andget_weight_version() -> int.int, starting at0for the constructor weights, instead of vLLM's opaquestr. One version then names exactly one weight state.reset_prefix_cache(reset_running_requests=False, reset_connector=False) -> bool, with vLLM's signature.get_weight_manifest() -> list[(name, shape, dtype)]: the deduplicated physical parameters (for Ouro and Nanbeige, exactly the HF checkpoint names; tied aliases and buffers are rejected).RequestOutput.weight_version: the version committed whenadd_requestran. It appears on every streamed, finished and aborted output.Lifecycle and failures
READY,UPDATINGandFAILED.add_requestraises unless the state isREADY.startcloses admission and requires the engine to be fully idle (no waiting, running, preempted or PD-in-flight request, no live KV allocation). It then syncs the runner streams, clears async tickets and exit signals, and resets the prefix cache.update_weightsvalidates the whole call before the first copy.fp32/fp16/bf16tensor on CPU or CUDA.param.copy_(src)in place and followed by a device sync. The caller may then reuse its buffers.finishrequires every manifest name exactly once. It then rechecks idleness and parameter addresses, and commits.vcomes from the weights committed asv. This includes reused prefix KV and P's prompt KV.State handling per feature
ouro,ouro_delayedandrandom_lookahead. The reset atstartfixes it.inv_freq.ourogate is a published parameter. The engine-ownedrandom_lookaheadprobe is not updated.PD (one update across all workers, driven by the coordinator)
(name, offset, shape)index.startorupdatemoves the engine toFAILED; a newstartrecovers.Out of scope
init_weight_transfer_enginewith NCCL/IPC transports,start_draft_weight_update, sleep/wake for colocated trainers, incremental or LoRA updates, Huginn, and Nanbeige on PD.Validation
data_ptr; rejections leave the state unchanged; an injected copy failure followed by a retry; versions on every output; every exit mode and self-speculation vs a fresh engine with the new weights; PD control via @0z5a's harness.copy_loop.Open questions
intversion instead of vLLM'sstr;pause_generation/resume_generationuntil PR 3?Co-authored-byon the commits that port Expose rollout logprobs and full policy publication on shared engines #78's code and tests, with Expose rollout logprobs and full policy publication on shared engines #78 then narrowed to what [FEAT] Rollout outputs: selected-token logprobs, effective seeds and stop token IDs (part of #70) #83 and PR 2 don't cover?global_steps=0first, but here0means the constructor weights. Could the 2A adapter publishglobal_steps + 1and bucket its per-tensor generator?feat: expose selected-token logprobs, effective seeds and stop token IDs
Levius-Fubuki commentedon Oct 13, 2026
Phase 2A update: draft PR in my verl fork, with reproduction instructions and experiment results. Two-GPU Ouro-1.4B BF16 runs completed three full-depth and three adaptive-exit RL iterations, exact next-step checkpoint recovery, and weight-publication checks across existing serving modes, including NIXL P/D and CUDA Graphs.
Current limits: this uses the pinned engine prototype and an in-process torchrun recipe; migration to the final shared API and production Ray integration remain. BF16 train/rollout selected logprobs differ by up to 0.341, so strict numerical parity is not established. These short runs make no convergence or speedup claim; the draft is ready for review, not yet accepted as complete.
I remain responsible for Phase 3 N+2 lookahead exit optimization, including predictor training and runtime integration. That is the next development stage and is not implemented in this PR.
MinhaoLi0318 commentedon Oct 14, 2026
@Levius-Fubuki, these are the changes verl#1 (
e901c2c) runs into when it moves from the #78 prototype (bdce287) to #83 (headdf66711) and PR 2:RequestOutput.log_probs;SamplingParams(logprobs_mode="raw"), read back inrollout_to_tensordictRequestOutput.logprobs; engine-levelLLM(..., logprobs_mode="raw_logprobs"), the default (#83, as your README notes)logprobs=0withspeculative_config(matrix modesspeculative,graphs_speculative)add_requestin #83 until the speculative-runner logprobs land, in #83 or as a follow-up PRRequestOutput.weight_version,start_weight_update(version=...),update_weights,finish_weight_update(),get_weight_version()LLM(PDEngine(...))in the P/D publication matrix (validate_adapter.py --pd), whichbdce287acceptsa32c89aor #83, whoseLLMtakes only a model or a path; my 10-06 design adds the methods toPDEngineitself but does not coverLLM(PDEngine(...))pause_generation()/resume_generation()around publicationstart_weight_updatecloses admission untilfinish_weight_updatecommitsAn update to my 10-06 design: PR 2 will name the keyword
version, notweight_version, in bothstart_weight_updateandfinish_weight_update, as #78 does forstart_weight_update. It stays optional, soOuroWeightPublishercan keep its calls as written. The effective seed stays atRequestOutput.sampling_params.seed, where your rollout reads it. verl#1 also already publishesglobal_steps + 1in buckets, which answers question 3 of the design.Could you confirm this table covers everything verl#1 needs from #83 and PR 2, before #83 leaves draft?
Thanks!
AI assistance: Claude Code drafted this and checked each row against verl#1
e901c2c, #78bdce287, #83df66711and maina32c89a; I reviewed it before posting.Levius-Fubuki commentedon Oct 14, 2026
@MinhaoLi0318 Confirmed: the table covers our current Phase 2A interface needs. I'll migrate to
RequestOutput.logprobsand engine-levelraw_logprobs, including the worker's probability checks.version=, effective seeds, and bucketedglobal_steps + 1publication work for us. For synchronous iterations, I'll use PR 2's admission fencing plus adapter-local lifecycle gating until PR 3.For P/D, I'll adapt the consumer around
PDEngine's public request/step/abort APIs;LLM(PDEngine(...))is not required. Speculative-logprob migration tests will remain pending until that support lands in #83 or its follow-up, then be rerun against the new revision. Existing speculative results apply only to the pinned prototype.Camellia86 commentedon Oct 14, 2026
I'd like to contribute an opt-in, experimental deferred Ouro decode path related to this RFC.
The intended users are Ouro rollout developers working with verl/vime. The goal is to improve rollout throughput under a measured quality budget. The main execution variable is the effective batch size of loops three and four: retain loop-two states across response positions, then execute a complete deep block at each fixed deep-readout boundary. Original token positions and separate, genuinely computed per-loop KV histories are preserved. This is a mixed shallow/deep readout policy; comparison with native K4 is a quality/performance tradeoff, while an eager implementation with the same readout schedule isolates the effect of deferring deep work.
I checked the existing prototype from vime PR #475 against current vllm-rlt main: all 28 CPU compatibility tests pass, covering readouts, every populated KV plane, grouped-query attention, staggered blocks, batch shrink, stopping, processed selected-token logprobs and independent seeded sampling. This establishes API and small-model causal correctness, not BF16 GPU performance or task quality.
The proposed PR will provide a standalone engine-side runner, a reproducible CLI example, correctness/lifecycle tests and documentation. A PR is useful because the reusable execution path should live in vllm-rlt without a dependency on a training framework. It will leave the normal inference entry points and their feature selection intact. I will open it as a draft with real-weight BF16 quality/performance/profiling and feature-combination qualification listed as unfinished. It will not claim completion of this RFC's training, weight-update or differentiable probability-replay deliverables.
feat: expose selected-token logprobs, effective seeds and stop token IDs
MinhaoLi0318 commentedon Oct 15, 2026
@bjf-frz one scoping question before I start PR 2. #78 (0z5a, now ready) exposes rollout logprobs and full policy publication on shared engines, and its description says
weight_versionand publication belong to PR 2 in the split from this RFC. #83 (PR 1) and #78 touch several of the same files, so I'd like to know which way you want to go:weight_versionon top, as Expose rollout logprobs and full policy publication on shared engines #78's description already suggests, orEither works for me; I just don't want two PRs implementing the same interface. cc @0z5a
AI assistance: drafted with Claude Code; I reviewed it before posting.
feat: add rollout sampling fields and logprob scoring primitives
feat: add rollout sampling fields and logprob scoring primitives