Repository navigation
Conversation
/v1/stats exposes cumulative token counts and sliding-window rates, but no cumulative time, so a client polling it cannot turn two polls into a speed: the 5 s windows decay to zero between polls, and a buffered request never records a TTFT at all. StatsTracker now times every request at the frontend chokepoint that already feeds it: prefill runs from admission to the request's first output reply, decode is the time between its later output replies, and decode_tokens_total counts only the tokens those later replies carried, so tokens delivered on the first reply (overlap) never inflate the decode rate. Times are summed per request, the same shape as llama.cpp's prompt/predicted seconds counters. cached_prompt_tokens_total sums the prefix-cache hits so a poller can exclude tokens that were never forwarded. New fields under "requests": prefill_seconds_total, decode_seconds_total, decode_tokens_total, cached_prompt_tokens_total. Existing fields are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
mgeldi
marked this pull request as ready for review
September 25, 2026 22:49
JUNQINGV587
added a commit
to JUNQINGV587/FreeToken
that referenced
this pull request
Sep 26, 2026
test_pinned_tensor keeps the measured 2xL20 UVA contract (the raw host_device_ptr rejects pageable memory even under UVA) over upstream FlashML-org#132's degenerate-identity assumption; test_stats_limits adds FlashML-org#553's cumulative timing fields to the stats mock.
JUNQINGV587
added a commit
to JUNQINGV587/FreeToken
that referenced
this pull request
Sep 26, 2026
KarrAcaRn
pushed a commit
to KarrAcaRn/FreeToken-ByAI
that referenced
this pull request
Oct 3, 2026
…refill and decode timing on /v1/stats Assisted-by: Claude Opus 5.5
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #552
What
Adds four cumulative counters to the
requestsobject of/v1/stats, so a process polling the server can diff two polls into prefill and decode tokens/s (the same way llama.cpp'sprompt_seconds_total/tokens_predicted_seconds_totalare used):prefill_seconds_totalnew_user) to its first output replydecode_seconds_totaldecode_tokens_totalcached_prompt_tokens_totalcached_tokens(prefix-cache hits)Everything is measured in
StatsTracker, which already observes every reply inFrontendManager.listen(), so streaming and buffered requests are timed the same way and nothing depends on reasoning/tool parsers holding text back. Tokens that arrive on a request's first output reply (overlap can deliver several) are not counted as decode work, because no decode interval measured them. Per-request timing state is released on the terminal reply. Existing fields and the window rates are unchanged.Tests
tests/server/test_stats_timing.py(5 tests): prefill/decode split, tokens on the first reply, two interleaved requests summed per request with state released, a request failing before output adds no time, and the fields inbuild_stats.pytest tests/server tests/scheduler/test_cost_accounting_core.py -m "not slow": 578 passed.ruff check --select E4,E7,E9,Fon the changed files: clean.Tested on
RTX 5090 32 GB, driver 615.71.09, CUDA 13.4, Ryzen 7 9800X3D, 91 GiB RAM, Linux 7.2.6 (CachyOS). Checkpoint
nvidia/Qwen3.8-Flash-Next-NVFP4(revfc694b54) converted to FTW (b12x) with FreeToken, branch based onf5b9700:Counters diffed around each request, compared with client-side timing from the SSE stream:
/v1/statsdeltattft_mean_ms9811), decode 299 tok / 7.53 s = 39.7 tok/scached_prompt_tokens_total+17,792The buffered request is the case the request ring cannot time today (
ttft_msisNonethere).AI-assisted: the change and tests were written with Claude Code, and the unit tests and live runs above were run on the hardware listed. I have reviewed the change.
🤖 Generated with Claude Code