Repository navigation
Conversation
|
One control-flow bug from reading the branch (not built here): in the restore block of |
93555e2 to
75e7df6
Compare
Thanks for the careful read — both points are valid. Fixed in 75e7df6:
Replaced with the same flag+break pattern the validate loop beside it uses: bool stage_limit_bad = false;
Bumped kVersionStages from 2 → 3. The version gate now explicitly rejects v2: if (version != kVersion && version != kVersionStages) { Also addressed while in here: Guard on save: if conversation_checkpoints_split routes any checkpoint to cs.rest (incomplete for the split), the save is refused rather than silently dropping it from the file. |
|
Tested on Linux with two NVIDIA A2 (Ampere, sm_86), a setup the PR description does not cover (it was checked on 2x RTX 5060 Ti, Windows, 6K tokens). This is a test report, not a code review. Setup: Strata v0.1.45 ( Merge: the branch does not merge into current Without the PR (v0.1.45), With the PR, one run each, engine restarted between save and restore:
Not tested: Test run and write-up with Claude. |
75e7df6 to
5e1ec82
Compare
Thanks for the thorough cross-platform test! A few notes: Merge conflict — resolved now; I just rebased onto current main ( 94K one-clause difference — sounds like decode non-determinism as you suspected. The restore is byte-identical (VRAM matches, same token reuse count: 94,435 of 94,468 reused), so the KV state is correct; the divergence is in attention numerics between a fresh 147s prompt pass and a restored state computed incrementally over many turns. Your observation that warm vs cold at 23K also differed once supports this — it's floating-point accumulation order, not a serialization bug. If you can reproduce it deterministically (same seed, PR title/description — updating now to say v3 (the code and commit already did; the GitHub page was stale). |
|
Thanks for the pull request. We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to review properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected. To reopen it takes about two minutes:
The rules are in CONTRIBUTING.md. |
|
/reopen |
|
Not reopened yet. Still missing:
Edit the pull request and comment |
|
/reopen |
|
Not reopened yet. Still missing:
Edit the pull request and comment |
|
/reopen |
|
The check passed, but GitHub would not reopen it (Validation Failed: ). If the branch was deleted, restore it or open a new pull request and link this one. |
Problem
When running Strata with
--layer-split autoacross multiple GPUs, the engine divides model layers into stages (one per GPU). The existing session save/restore (--slot-save-path) only handled a single-stage (single-GPU) layout: it saved/restored one set of running state and K/V. On a multi-GPU split, the save was either refused or produced an incomplete file that couldn't be restored.This made
--slot-save-pathunusable for the most common multi-GPU configuration, which is exactly where long-context session persistence matters most (the RAM cost of re-reading a 30K+ token prompt).Solution
Introduce format v3 for session files that carries per-stage data. Version 2 is reserved for PR #2247's BF16 state codec; this build rejects it explicitly at the version gate.
put_payloadserializes stage 0 (as before), then — only whenstage_imagesis non-empty — a count followed by one block per later stage. Each block holds that stage's running state, K/V parts, and checkpoint. The file header version is set tokVersionStages = 3.get_payloadreads stage 0 identically to v1, then checks the version. For v3 files it reads the stage count (bounded bylimits.max_stages) and each subsequent stage block, validating geometry and layer range per stage. A v1 file has no stage section; a v2 file is refused at the version gate (not silently misparsed as v1).conversation_checkpoints_splitroutes any checkpoint tocs.rest(incomplete for the split), the save is refused rather than silently dropping it.Read-limit hardening
SessionReadLimitsgainsmax_stagesand a per-stagestage_limitsvector. The serve loop populates these from the live engine's stage carves before callingsession_file_read, so a file from a different split (wrong stage count, wrong layer range, oversized K/V) is refused before any allocation — not after a partial read.Changes by file
include/strata/core/conversation_file.hppkVersionStages = 3,SessionReadLimits::max_stages,stage_limits,SessionStageLimitsstructinclude/strata/core/conversation_snapshot.hppconversation_stage_read_limits()declarationsrc/core/conversation_file.cppput_payload), v3 read (get_payload), per-stage validation, explicit v2 rejectionsrc/core/conversation_state.cppconversation_stage_read_limits()implementation,conversation_session_read_limitsupdated to carry stage boundssrc/program/generate.cppstage_limitsfrom live stages, setmax_stages, pass through to read; save path collects per-stage K/V sources;cs.restguard;draft_stage_kvhelpersrc/core/conversation_file_test.cppsrc/core/conversation_snapshot_test.cppconversation_stage_read_limitsunit testsEnvironment
Strata built from source, CUDA 13.4, Windows 11 / Debian 13
2× NVIDIA RTX 5060 Ti (16 GB) or 2× NVIDIA A2 (16 GB), 64 GB system RAM
Qwen3.8-Flash-Next Coder IQ3_XXS / UD-Q4_K_XL, up to 128K context
Validation
Revision:
94f55cd6(rebased onto maine88ee39d, 0.2.0-beta)Environment: CUDA 13.4, Windows 11, 2× NVIDIA RTX 5060 Ti 16 GB (sm_120), 64 GB RAM
Commands:
Passed:
Failed: none
Not run:
--batch/ parallel slots