Repository navigation
server: optional idle unload, /unload and /load, a free-VRAM guard (share the GPU with other programs) - #208
bytethecookie wants to merge 3 commits into
Conversation
|
Useful and well tested. Two asks: set |
…rd and a before_load hook Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… sharing the GPU Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ngine to QUIT first, docs: the VRAM check looks at the first GPU - Service.load() sets last_request_at, so the idle thread can't unload between load() and the request - StrataEngine.unload() sends QUIT (as close() does) and only terminates/kills if the engine doesn't end - /metrics reads the 'unloaded' flag instead of probing the process (upstream's LiveRate test stubs proc) - tests: load counts as activity; a fake engine proves unload() takes the QUIT path Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for the review — all three are in (a57f1f8), and the branch is rebased onto current main (0.1.29):
One more change came out of the rebase: your new Checked on the real engine (0.1.29, RTX 5060 Ti 16 GB, Q2_0 low-RAM mode): unloading through |
88a458e to
a57f1f8
Compare
…rom 1024-token chunks), the resident low-RAM variant, the multi-GPU session carve (#216), AMD RDNA4, idle unload (#208); opt-ins: rope scaling (#84), conversation cache (#189), STRATA_IQ_MT_MIN=1 (#152); setup requires it Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
|
Released in 0.1.30: with three small follow-ups (a request stamps |
…load() (the idle thread cannot unload between load and run); unload() sends QUIT before terminate; the VRAM guard checks the first GPU (docs); Niko1221#163's test engine answers poll() Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
…g, the split sampler, fixes Upstream's 103 commits since a790805, with this branch's engine kept wherever both sides do the same thing (the prompt path, the verify window's kernels, the QSA block scores, the prompt cache, --ple-io ram). Taken: - serve/: upstream's server: optional idle unload, POST /unload and /load, a free-VRAM guard and a before_load hook (Niko1221#208); /status behind the API key (Niko1221#212) and a constant-time key check (Niko1221#213); an engine exit quotes its last log line (Niko1221#215); tool calls end at their own </parameter> (Niko1221#210); the engine, the image encoder and the MCP servers end with the server on Windows; no stack trace when a client hangs up; the prompt speed on the dashboard; SIGTERM. Without a "gpu" key in the config, the Monitor and the VRAM guard read the cards of --main-gpu and --second-gpu. - Sampling: top_k by a lexicographic threshold, split over the whole GPU (Niko1221#197, the same tokens). - Fixes: the session state zeroed at start in generate mode (Niko1221#167); a serve request that fails on a CUDA fault exits at once (Niko1221#224), and every failed request's reason goes to the log; the error string cleared per request; the expert cache shrinks by 1 GiB steps when the free VRAM reads 0 (Niko1221#153), and says so when no VRAM is left for it (Niko1221#174); s_gemv's q8 split kernel reaches its barrier; a NaN stays a quiet NaN in f32 -> bf16; NOMINMAX; iq_pack writes native_experts.txt under a temporary name (Niko1221#172). - STRATA_IQ_MT_MIN=1 (opt-in, Niko1221#152), the AVX-2 i-quant prefetch, the table indexer's spare rotated at position 0 (bitwise unscaled), version 0.1.30; tests: mmvq_multi_parity, bf16_bits_test, the sampler's three paths. - setup.py, docs, Docker, the AMD RDNA4 and Pascal files (not built here), data/draft_vocab_en.bin (byte-identical to this branch's data/draft_vocab.bin). DETAILS.md gains the GPU-sharing options, STRATA_IQ_MT_MIN and this branch's draft vocabulary; examples/README.md lists the upstream options this branch's engine leaves out. Not taken: rope scaling (contexts past 262K; the QSA RoPE kernels keep their form), the conversation cache (the prompt cache stashes replaced conversations), the low-RAM resident variant, the multi-GPU session carve, coupled draft sampling, the shared expert arena (Linux), the WSL2 context order, upstream's GDN recurrence pipelining and its 1024-token expert streaming (this branch's prompt path has its own forms), STATE_HASH. Their files are in the tree, not built. Window hashes on fixed text (--adapt-every 0, the second GPU's tier pinned) equal the previous build's on both models; the API tests (prompt cache, streaming, keep-alives, disconnect) pass. Claude-Session: https://claude.ai/code/session_01GgM6qCebHZfQmgkcxNY1U5
…load() (the idle thread cannot unload between load and run); unload() sends QUIT before terminate; the VRAM guard checks the first GPU (docs); Niko1221#163's test engine answers poll()
…load() (the idle thread cannot unload between load and run); unload() sends QUIT before terminate; the VRAM guard checks the first GPU (docs); Niko1221#163's test engine answers poll()
…rom 1024-token chunks), the resident low-RAM variant, the multi-GPU session carve (Niko1221#216), AMD RDNA4, idle unload (Niko1221#208); opt-ins: rope scaling (Niko1221#84), conversation cache (Niko1221#189), STRATA_IQ_MT_MIN=1 (Niko1221#152); setup requires it
…load() (the idle thread cannot unload between load and run); unload() sends QUIT before terminate; the VRAM guard checks the first GPU (docs); Niko1221#163's test engine answers poll() Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
…rom 1024-token chunks), the resident low-RAM variant, the multi-GPU session carve (Niko1221#216), AMD RDNA4, idle unload (Niko1221#208); opt-ins: rope scaling (Niko1221#84), conversation cache (Niko1221#189), STRATA_IQ_MT_MIN=1 (Niko1221#152); setup requires it Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
What
Optional support for sharing the GPU with other programs: Strata can unload the model when it is idle and load it again on the next request. Everything is off by default — without the new options the server behaves exactly as before.
--idle-unload SECONDSidle_unload_s--min-free-vram-mib Nmin_free_vram_mib503"the GPU is in use by another program"--before-load CMDbefore_load(string or list)Plus
POST /unload(409while a request is running) andPOST /load;/healthgains"loaded",/v1/modelslists the model with statusunloaded(like llama.cpp's router, building on #122's endpoints),/propssetsis_sleeping, and/metricsreports the stateunloaded.Why
Strata fills all free VRAM and holds it until the window is closed. On a PC that also games, runs ComfyUI or another model server, that means stopping and starting Strata by hand. With these options it can stay up permanently next to them.
How
restart()path from Generation stops after few hundred tokens in v0.1.8 #27 — the "engine died, start it again" check inrun()now goes through oneensure_loaded()that also handles a deliberate unload.503rather than an error mid-stream._Nvmlclass intelemetry.py; if it can't be read, nothing is refused.busy/queued).Measured
RTX 5060 Ti 16 GB, i5-12400F, 48 GB DDR4, Linux (Docker), Q2_0 with
--mmap-experts, files in the OS cache:POST /unloadreturns after ~0.33 s with the VRAM free (15.7 GB -> 0.76 GB used)--min-free-vram-mib 11000:503after the 15 s wait, model stays unloadedI run it this way next to llama.cpp's router and ComfyUI:
--idle-unload 120 --min-free-vram-mib 11000 --before-load "<script that unloads llama-server's models>".Tests
python -m unittest serve.test_server: the 39 existing tests pass unchanged, plus 9 new ones inSharingTheGpu(unload then reload on the next request,/load, refused while busy, idle unload, the VRAM guard refusing and then loading, unreadable VRAM never refusing,before_loadrunning first, the encoder unloading and starting first, off by default).Notes for review
POST /unloadand/loadfollow the API-key check like the other POST routes but not the_own_pagecheck that/settingshas, since other programs on the machine are the intended callers. The worst a cross-site request could do is unload an idle model.terminate()on Windows is a hard kill, which should be fine for a process between requests, but it is untested.docs/DETAILS.md. Setup does not ask about any of this; it seemed better left as an advanced option.🤖 Generated with Claude Code