Skip to content

common, server : report model input/output modalities in GET /models - #29987

Merged
ngxson merged 1 commit into
ggml-org:masterfrom
angt:common-server-report-model-input-output-modalities-in-get-models
Oct 5, 2026
Merged

ngxson merged 1 commit into
ggml-org:masterfrom
angt:common-server-report-model-input-output-modalities-in-get-models

Conversation

@angt

@angt angt commented Oct 5, 2026

Copy link
Copy Markdown
Member

Overview

Proposal to add an architecture object to GET /v1/models and GET /models.
This object gives the model input and output modalities.

Additional information

Supersedes #29944

Requirements

Signed-off-by: Adrien Gallouët <angt@huggingface.co>
@angt
angt requested review from a team as code owners October 5, 2026 10:07
@github-actions github-actions Bot added documentation Improvements or additions to documentation server labels Oct 5, 2026
@angt

angt commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

@ngxson This PR may do a bit more than needed but I think the changes are still reasonable.
But I can make it smaller by keeping the existing input-modality handling and only updating output_modalities, if you prefer.

@ngxson ngxson left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the impl is a bit convoluted: same notion is spread out to multiple files and ti's unclear about the data flow

Instead, I might be better to:

  • Have a struct server_model_architecture and pass the struct around, instead of passing json
  • server_model_architecture::to_json() renders it into json, same idea as server_task_result
  • server_model_architecture constructor can take either const llama_model * (server_context case) or string model_path (router case)

Also, additions to docs should be minimal, since it's an user-facing docs

Comment thread tools/server/README.md
Comment on lines +1264 to +1273
Check for membership. Tolerate values that you do not know:

```js
const useSystemOne =
model.architecture?.output_modalities?.includes("decisions") === true;
```

Without decision metadata, `output_modalities` is `["text"]`. This default is for compatibility only. It does not mean that the model can generate text. Values can change. New combinations such as `["text", "decisions"]` use the same shape.

The router returns the same `architecture` object in [`GET /models`](#get-models-list-available-models). You can find a native decision model without a probe or a model load. This works for unloaded and sleeping models too. Older servers can omit `architecture`. If it is absent, use the legacy behavior of your client.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe simplify this part to only specify core technical specs, for example "Tolerate values" and "Older servers can omit" are trivial to know and don't need to be in docs

Comment thread tools/server/README.md
Comment on lines +2042 to +2050

The values work like this:

- A loaded model reports both arrays. Its values replace the cached values in full.
- The cache keeps the values across sleep and unload. A known decision model stays advertised.
- Before the first report, the values come from the offline computation.
- Offline computation cannot see video. Only a loaded model reports `video` in `input_modalities`.
- If the metadata or the model file is not available, both arrays are `["text"]`.
- A source or preset refresh computes both arrays again. A replaced model does not keep old values.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove redundant impl details in docs, they will add maintenance costs

// model output modalities
//

std::vector<std::string> server_model_output_modalities(common_decision_type decision_type) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be part of server-decision ?

/* model_aliases */ impl->model_aliases,
/* model_tags */ impl->model_tags,
/* model_path */ impl->params_base.model.path,
/* model_output_modalities */ server_model_output_modalities(common_get_decision_type(impl->model_tgt)),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the whole architecture object should be stored here, not just the output part

Comment on lines +1320 to 1341
// the child replaces both arrays in full; a bad or missing value changes nothing
if (args.loaded_info.contains("architecture") && args.loaded_info.at("architecture").is_object()) {
const json & child_arch = args.loaded_info.at("architecture");
for (const char * key : { "input_modalities", "output_modalities" }) {
if (!child_arch.contains(key) || !child_arch.at(key).is_array()) {
continue;
}
std::vector<std::string> modalities;
bool valid = true;
for (const auto & m : child_arch.at(key)) {
if (!m.is_string()) {
valid = false;
break;
}
modalities.push_back(m.get<std::string>());
}
if (valid) {
meta.architecture[key] = std::move(modalities);
}
}
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if we really need this part? looks quite overkill, ~20 LOC for an edge case that may never happen in reality

@ngxson ngxson left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's merge this version to have it in v0.6 release, I will push a follow-up to clean up the internal code

cc @ggerganov

@ngxson
ngxson merged commit 4d60b4d into ggml-org:master Oct 5, 2026
12 checks passed
@angt

angt commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

The cleanup was arriving, sorry 😅

@angt

angt commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

I was in agreement with all the points but testing takes time: https://github.com/angt/llama.cpp/tree/common-server-report-model-input-output-modalities-in-get-models-minimal

@angt
angt deleted the common-server-report-model-input-output-modalities-in-get-models branch October 6, 2026 06:28
mitsuhiko added a commit to earendil-works/pi that referenced this pull request Oct 6, 2026
…alities

llama.cpp 0.6.0 reports decisions in architecture.output_modalities of
GET /models (ggml-org/llama.cpp#29987), including for unloaded and
sleeping models. Use it instead of probing /v1/systemone and remembering
probe results across sessions.
Wizard815 added a commit to Wizard815/mx-llama.cpp-Rocm10 that referenced this pull request Oct 6, 2026
ggml-org#29903 also enables embedding mode for the laya/kev/clef decision models, but
that half calls common_get_decision_type() and references the
COMMON_DECISION_TYPE_* enums, which arrived in the post-0.5.0 commits
a4cb4c6 (ggml-org#29818) and 4d60b4d (ggml-org#29987) and are absent here:

  common.cpp:1345: error: 'common_get_decision_type' was not declared in this scope

Keep the n_batch <= n_ubatch clamp, which is self-contained and the part the
commit is named for. The decision-model block can return once those upstream
commits are merged.

Assisted-by: Hermes Agent
thelittlefireman pushed a commit to thelittlefireman/llama.cpp that referenced this pull request Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants