char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
947fd9bb2
char/aliceai-t5-moe
1import pytest 2import time 3from utils import * 4 5server = ServerPreset .tinyllama2 () 6 7 8@ pytest . fixture ( autouse = True ) 9def create_server (): 10global server 11server = ServerPreset .tinyllama2 () 12 13 14def is_sleeping (server :ServerProcess )-> bool : 15res = server .make_request ("GET" ,"/props" ) 16assert res .status_code == 200 17return res .body ["is_sleeping" ] 18 19 20def wait_for_sleep (server :ServerProcess ,timeout :float = 10.0 ): 21start = time .time () 22while time .time ()- start < timeout : 23if is_sleeping (server ): 24return 25time .sleep (0.1 ) 26raise TimeoutError ("server did not go to sleep" ) 27 28 29def fetch_metrics (server :ServerProcess )-> str : 30res = server .make_request ("GET" ,"/metrics" ) 31assert res .status_code == 200 32assert isinstance (res .body ,str ) 33return res .body 34 35 36def get_metric (text :str ,name :str )-> float : 37prefix = f"llamacpp: { name } " 38values = [ln for ln in text .splitlines ()if ln .startswith (prefix )] 39assert len (values )== 1 ,f" { name } not found in metrics" 40return float (values [0 ][len (prefix ):]) 41 42 43def test_server_sleep (): 44global server 45server .sleep_idle_seconds = 1 46server .start () 47 48# wait a bit so that server can go to sleep 49time .sleep (2 ) 50 51# make sure these endpoints are still responsive after sleep 52res = server .make_request ("GET" ,"/health" ) 53assert res .status_code == 200 54res = server .make_request ("GET" ,"/props" ) 55assert res .status_code == 200 56assert res .body ["is_sleeping" ]== True 57res = server .make_request ("GET" ,"/models" ) 58assert res .status_code == 200 59assert len (res .body ["data" ])== 1 60assert res .body ["data" ][0 ]["id" ]== server .model_alias 61 62# make a generation request to wake up the server 63res = server .make_request ("POST" ,"/completion" ,data = { 64"n_predict" :1 , 65"prompt" :"Hello" , 66 }) 67assert res .status_code == 200 68 69# it should no longer be sleeping 70res = server .make_request ("GET" ,"/props" ) 71assert res .status_code == 200 72assert res .body ["is_sleeping" ]== False 73 74 75def test_server_sleep_read_only_endpoints (): 76global server 77server .sleep_idle_seconds = 1 78server .server_metrics = True 79server .start () 80 81res = server .make_request ("POST" ,"/completion" ,data = { 82"n_predict" :4 , 83"prompt" :"Hello" , 84 }) 85assert res .status_code == 200 86 87# the first scrape resets the throughput buckets, so that the second one reports 88# the same zero rates as the snapshot taken on entering sleep 89fetch_metrics (server ) 90metrics_awake = fetch_metrics (server ) 91assert get_metric (metrics_awake ,"tokens_predicted_total" )> 0 92 93wait_for_sleep (server ) 94 95# during sleep, metrics are served from the snapshot taken right before sleeping 96assert fetch_metrics (server )== metrics_awake 97 98# scraping /metrics must not wake the server up 99assert is_sleeping (server ) 100 101 102def test_server_sleep_metrics_buckets (): 103global server 104server .sleep_idle_seconds = 1 105server .server_metrics = True 106server .start () 107 108res = server .make_request ("POST" ,"/completion" ,data = { 109"n_predict" :8 , 110"prompt" :"Hello" , 111 }) 112assert res .status_code == 200 113 114wait_for_sleep (server ) 115 116# the first scrape reports the throughput of the last generation 117assert get_metric (fetch_metrics (server ),"predicted_tokens_seconds" )> 0 118 119# nothing runs while sleeping, so the next scrapes report an empty window 120assert get_metric (fetch_metrics (server ),"predicted_tokens_seconds" )== 0 121assert is_sleeping (server ) 122 123# waking up must not report the buckets again 124res = server .make_request ("POST" ,"/tokenize" ,data = {"content" :"Hello" }) 125assert res .status_code == 200 126assert is_sleeping (server )== False 127assert get_metric (fetch_metrics (server ),"predicted_tokens_seconds" )== 0