You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When running llama-server in router mode with --models-preset flag, the /metrics endpoint currently requires specifying a model via query parameter (e.g., /metrics?model=my-model). This means metrics can only be retrieved for one model at a time.
Proposal
Provide an aggregated metrics endpoint at /metrics (without the model parameter), same as the current single-model behaviour, that exports Prometheus metrics from all currently loaded models, using a model label to differentiate them.
Example output:
# HELP llamacpp_tokens_predicted_total Number of generation tokens processed.
# TYPE llamacpp_tokens_predicted_total counter
llamacpp_tokens_predicted_total{model="gemma-3-4b-it"} 1234
llamacpp_tokens_predicted_total{model="llama-3-8b-instruct"} 5678
# HELP llamacpp_prompt_tokens_total Number of prompt tokens processed.
# TYPE llamacpp_prompt_tokens_total counter
llamacpp_prompt_tokens_total{model="gemma-3-4b-it"} 9000
llamacpp_prompt_tokens_total{model="llama-3-8b-instruct"} 12000
# HELP llamacpp_requests_processing Number of requests currently being processed.
# TYPE llamacpp_requests_processing gauge
llamacpp_requests_processing{model="gemma-3-4b-it"} 2
llamacpp_requests_processing{model="llama-3-8b-instruct"} 0
Motivation
Single scrape target for Prometheus: Currently, to monitor all models, you would need to query each model's metrics individually. This is cumbersome and doesn't work well with Prometheus's service discovery model, which expects a single /metrics endpoint per target.
Dynamic model loading: In router mode, models can be loaded and unloaded dynamically. With the current design, a Prometheus configuration would need to be updated every time models change. An aggregated endpoint solves this - Prometheus scrapes one endpoint and automatically gets metrics for whatever models are currently loaded.
Standard Prometheus pattern: Using labels (like model="...") to differentiate instances is the idiomatic Prometheus approach. This enables powerful PromQL queries like:
sum(rate(llamacpp_tokens_predicted_total[5m])) by (model) - throughput per model
sum(llamacpp_requests_processing) - total active requests across all models
Operational simplicity: Operators running multi-model deployments can use a single Grafana dashboard with model selectors rather than managing separate dashboards or complex federation setups.
Possible Implementation
The router already tracks loaded models and their ports in server_models. A possible implementation:
When /metrics is called without a model parameter in router mode, the router iterates over all loaded model instances
For each loaded model, the router makes an internal HTTP request to the child's /metrics endpoint
The router parses each child's Prometheus output and adds a model="<model-name>" label to each metric
The aggregated output is returned to the client
Considerations
Caching: To avoid hammering child processes, the router could cache metrics for a short period (e.g., 5-15 seconds)
Timeouts: If a child is slow to respond, the router should use a short timeout and either skip that model or return partial results
Router-level metrics: The router could also export its own metrics (e.g., llamacpp_router_models_loaded, llamacpp_router_requests_total)
If the proposal is acceptable, I could take a stab at the implementation.
So, I wanted to have this sort of support. It is currently doable without any changes to llama-server. I have all my models monitored like so, by using http service-discovery:
this runs in a uvicorn docker image to make requests to llama-server's model endpoint to determine loaded models, and return target information to prometheus
fromfastapiimportFastAPIfromfastapi.responsesimportJSONResponseimporthttpximportjsonfromurllib.parseimportquoteimporttracebackapp=FastAPI()
@app.get("/targets.json")asyncdefget_targets():
try:
# Fetch models from the models endpointasyncwithhttpx.AsyncClient() asclient:
models_response=awaitclient.get("http://host.docker.internal:8080/models")
models_data=models_response.json()
# Parse models and find loaded onestargets= []
formodelinmodels_data.get("data", []):
model_id=model["id"]
status_value=model.get("status", {}).get("value", "")
ifstatus_value=="loaded":
targets.append({
"targets": ["host.docker.internal:8080"],
"labels": {
"llama_model_id": model_id,
}
})
returnJSONResponse(targets)
exceptExceptionase:
# Return empty targets list on error to keep current targetstraceback.print_exc()
returnJSONResponse([str(e)])
if__name__=="__main__":
importuvicornuvicorn.run(app, host="0.0.0.0", port=8080)
With this setup, I am able to import all my metrics into prometheus, and then chart them in grafana. Models that are loaded and unloaded are automatically detected and metrics fetching starts for loaded models and stops for unloaded models.
edit: I suppose I could proxy all the /metrics requests directly at this point, but I don't think there's no real value in doing that, other than making the prometheus configuration a little simpler.
Hi, I'm having trouble importing from prometheus to grafana because I haven't found a dashboard json anywhere online, to my great surprise. Would you care to send me yours or give me pointers on how to make it? Thanks!
Thank you very much I couldn't have pulled it off without that. I had to change the "uid": "efc2.*" to "name": "${datasource}" and a few things here and there
A model that's technically asleep will still show as "loaded" - is there a way we can filter those out from the targets.json so that scraping doesn't wake up a sleeping model?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Exposition
When running
llama-serverin router mode with--models-presetflag, the/metricsendpoint currently requires specifying a model via query parameter (e.g.,/metrics?model=my-model). This means metrics can only be retrieved for one model at a time.Proposal
Provide an aggregated metrics endpoint at
/metrics(without themodelparameter), same as the current single-model behaviour, that exports Prometheus metrics from all currently loaded models, using amodellabel to differentiate them.Example output:
Motivation
sum(rate(llamacpp_tokens_predicted_total[5m])) by (model)- throughput per modelsum(llamacpp_requests_processing)- total active requests across all modelsPossible Implementation
The router already tracks loaded models and their ports in server_models. A possible implementation:
/metricsis called without a model parameter in router mode, the router iterates over all loaded model instancesmodel="<model-name>"label to each metricConsiderations
llamacpp_router_models_loaded,llamacpp_router_requests_total)If the proposal is acceptable, I could take a stab at the implementation.
All reactions