e93507a09c
Lockfile supply-chain audit / lockfile supply-chain audit (push) Has been cancelled
Windows Studio GGUF CI / GPU prebuilt resolves without Visual Studio (push) Has been cancelled
Windows Studio GGUF CI / setup.ps1 unit tests (VS 2026 / CMake guard) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2022) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-2025-vs2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-latest) (push) Has been cancelled
Windows Studio Update CI / Studio Updating Tests (push) Has been cancelled
Wheel CI / Wheel build + content sanity + import smoke (push) Has been cancelled
Lint CI / Source lint (Python + shell + YAML + JSON + safety nets) (push) Has been cancelled
MLX CI on Mac M1 / dispatch (push) Has been cancelled
Security audit / advisory audit (pip + npm + cargo) (push) Has been cancelled
Security audit / pip scan-packages :: extras (push) Has been cancelled
Security audit / pip scan-packages :: studio (push) Has been cancelled
Security audit / pip scan-packages :: hf-stack (push) Has been cancelled
Security audit / npm scan-packages (Studio frontend tarballs) (push) Has been cancelled
Security audit / workflow-trigger lint (pull_request_target / cache-poisoning) (push) Has been cancelled
Security audit / pytest tests/security (push) Has been cancelled
Security audit / npm provenance + new install-script diff (push) Has been cancelled
Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Backend CI / (Python 3.10) (push) Has been cancelled
Backend CI / (Python 3.11) (push) Has been cancelled
Backend CI / (Python 3.12) (push) Has been cancelled
Backend CI / (Python 3.13) (push) Has been cancelled
Backend CI / Repo tests (CPU) (push) Has been cancelled
Frontend CI / Frontend build + bundle sanity (push) Has been cancelled
Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Mac Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Mac Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-14) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15-intel) (push) Has been cancelled
Mac Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26-intel) (push) Has been cancelled
Mac Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Tauri CI / Tauri Linux debug build (no codesign) (push) Has been cancelled
Mac Studio Update CI / Studio Updating Tests (push) Has been cancelled
Studio UI CI / Chat UI Tests (push) Has been cancelled
Windows Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Windows Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Update CI / Studio Updating Tests (push) Has been cancelled
Core / Core (HF=default + TRL=default) (push) Has been cancelled
Core / Core (HF=4.57.6 + TRL<1) (push) Has been cancelled
Core / Core (HF=latest + TRL=latest) (push) Has been cancelled
Core / llama.cpp build + smoke (push) Has been cancelled
Windows Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Windows Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Windows Studio GGUF CI / JSON, images (push) Has been cancelled
Windows Studio GGUF CI / Studio install + inference without Visual Studio (push) Has been cancelled
Studio export capability / capability (macos-latest) (push) Has been cancelled
Studio export capability / capability (ubuntu-latest) (push) Has been cancelled
Studio export capability / capability (windows-latest) (push) Has been cancelled
Cross-platform parity / parity (macos-latest) (push) Has been cancelled
Cross-platform parity / parity (windows-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Studio load-orchestrator CI / test (push) Has been cancelled
129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-only
|
|
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
|
|
|
"""Tests for the llama-server /metrics -> engine_stats translator: generation
|
|
throughput comes from generated-token metrics (not llama_decode() calls), and
|
|
the unexposed kv_cache_usage_ratio is never fabricated into the log line."""
|
|
|
|
from core.inference.llama_stats import LlamaServerStatsLogger
|
|
|
|
|
|
class _Capture:
|
|
def __init__(self):
|
|
self.events = []
|
|
|
|
def info(self, event, **kw):
|
|
self.events.append((event, dict(kw)))
|
|
|
|
def debug(self, *a, **k):
|
|
pass
|
|
|
|
|
|
def _drive(snaps):
|
|
"""Run _run() synchronously over `snaps`, then stop deterministically."""
|
|
cap = _Capture()
|
|
lg = LlamaServerStatsLogger("http://127.0.0.1:0", cap)
|
|
lg._interval = 0.001 # bypass the 1s floor for a fast, synchronous run
|
|
state = {"i": 0}
|
|
|
|
def fake_scrape():
|
|
i = state["i"]
|
|
state["i"] += 1
|
|
if i >= len(snaps):
|
|
lg.stop()
|
|
return None
|
|
return snaps[i]
|
|
|
|
lg._scrape = fake_scrape
|
|
lg._run()
|
|
return [kw for ev, kw in cap.events if ev == "engine_stats"]
|
|
|
|
|
|
def test_gen_tok_s_uses_token_metrics_not_decode_calls():
|
|
# tokens_predicted_total jumps 95 while n_decode_total only moves 9; the
|
|
# gauge reports 95 tok/s. Decode-call rate (9) must not be reported.
|
|
snaps = [
|
|
{
|
|
"tokens_predicted_total": 0.0,
|
|
"prompt_tokens_total": 0.0,
|
|
"n_decode_total": 0.0,
|
|
"predicted_tokens_seconds": 95.0,
|
|
"prompt_tokens_seconds": 30.0,
|
|
"requests_processing": 1.0,
|
|
},
|
|
{
|
|
"tokens_predicted_total": 95.0,
|
|
"prompt_tokens_total": 30.0,
|
|
"n_decode_total": 9.0,
|
|
"predicted_tokens_seconds": 95.0,
|
|
"prompt_tokens_seconds": 30.0,
|
|
"requests_processing": 1.0,
|
|
},
|
|
]
|
|
stats = _drive(snaps)
|
|
assert stats, "expected engine_stats while a request is processing"
|
|
assert all(s["gen_tok_s"] == 95.0 for s in stats)
|
|
assert all(s["prompt_tok_s"] == 30.0 for s in stats)
|
|
|
|
|
|
def test_kv_cache_pct_not_emitted_when_metric_absent():
|
|
# llama.cpp does not expose kv_cache_usage_ratio, so it must not appear.
|
|
snaps = [
|
|
{
|
|
"tokens_predicted_total": 0.0,
|
|
"prompt_tokens_total": 0.0,
|
|
"predicted_tokens_seconds": 10.0,
|
|
"requests_processing": 1.0,
|
|
},
|
|
{
|
|
"tokens_predicted_total": 10.0,
|
|
"prompt_tokens_total": 5.0,
|
|
"predicted_tokens_seconds": 10.0,
|
|
"requests_processing": 1.0,
|
|
},
|
|
]
|
|
stats = _drive(snaps)
|
|
assert stats
|
|
assert all("kv_cache_pct" not in s for s in stats)
|
|
|
|
|
|
def test_scrape_parses_labelled_and_bare_metrics(monkeypatch):
|
|
# Prometheus samples may carry labels; both labelled and bare lines parse.
|
|
import core.inference.llama_stats as ls
|
|
|
|
body = (
|
|
'llamacpp:tokens_predicted_total{model="m"} 20\n'
|
|
'llamacpp:prompt_tokens_total{model="m"} 5\n'
|
|
"llamacpp:requests_processing 1\n"
|
|
"# HELP llamacpp:ignored ignored\n"
|
|
)
|
|
|
|
class _Resp:
|
|
status = 200
|
|
|
|
def read(self):
|
|
return body.encode()
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, *a):
|
|
return False
|
|
|
|
monkeypatch.setattr(ls.urllib.request, "urlopen", lambda *a, **k: _Resp())
|
|
m = ls.LlamaServerStatsLogger("http://127.0.0.1:0", _Capture())._scrape()
|
|
assert m["tokens_predicted_total"] == 20.0
|
|
assert m["prompt_tokens_total"] == 5.0
|
|
assert m["requests_processing"] == 1.0
|
|
|
|
|
|
def test_counter_delta_fallback_without_gauges():
|
|
# Older binaries expose only the counters; throughput falls back to deltas.
|
|
snaps = [
|
|
{"tokens_predicted_total": 100.0, "prompt_tokens_total": 0.0, "requests_processing": 1.0},
|
|
{"tokens_predicted_total": 100.0, "prompt_tokens_total": 0.0, "requests_processing": 1.0},
|
|
]
|
|
stats = _drive(snaps)
|
|
# running=1 keeps it emitting; gen_tok_s falls back to the (here zero) delta.
|
|
assert stats and all(s["gen_tok_s"] >= 0.0 for s in stats)
|