Merged & Retrained Models
Models produced by merge or
retrain-on-top are not a special class of artifact. Each
is an ordinary model_version in your catalog: it is served through the normal inference path and can
be reused as a base for the next operation — exactly like any trained model.
How they appear in the catalog
A merged or retrained model shows up alongside your other trained models:
for m in client.models.list():
print(m.model_id, m.framework)
# Its versions carry lineage metadata
for v in client.models.versions("MODEL_UUID"):
print(v["version_id"], v.get("framework"), v.get("precision"), v.get("base_model_version_id"))
Each version records:
| Field | Merge output | Retrain output |
|---|---|---|
framework | transformers | inherited from the training template |
precision | bf16 (never re-quantized) | per the training template |
base_model_version_id | primary input (adapter/source) | the base it was retrained on |
training_job_id | the merge job (job_type=merge) | the training job |
In an agent's MCP manifest they surface as kind=trained_model with a populated lineage block, just
like any other trained model (see Tools Reference).
How they are served
A merged model is a full model (framework=transformers, precision=bf16), so it serves through
the standard inference path (vLLM / transformers) with no special handling. Promote it to an endpoint
and run inference like any trained run:
endpoint = client.training.register_for_inference(
run_id="MERGE_JOB_UUID",
name="qwen-domain-base",
description="Base model with domain adapter merged in.",
visibility="account", # or "public" to let other accounts reuse it as a base
)
result = client.endpoints.infer(endpoint.endpoint_id, {"messages": [{"role": "user", "content": "Hi"}]})
A freshly produced model enters as candidate. After a successful inference test it is promoted to
ready. Do not treat a candidate model as production-ready. See
Inference Lifecycle.
How they are reused as a base
Because the result is a normal model_version, you point at it by version_id to keep the flywheel
turning:
# Merge another adapter into it
client.training.merge(
name="qwen-domain-base-v2",
base={"type": "model_version", "version_id": "MERGED_VERSION_UUID"},
adapters=[{"type": "model_version", "version_id": "NEW_ADAPTER_VERSION_UUID"}],
)
# ...or retrain on top of it
client.training.create(
model="MODEL_CONFIG_UUID",
dataset_id="DATASET_UUID",
base={"type": "model_version", "version_id": "MERGED_VERSION_UUID"},
hyperparameters={"num_epochs": 2},
)
Visibility & reuse across accounts: a private version can only be used as a base by its owner. To
let another account build on it, publish it (visibility=public). Lineage records the origin either
way.
Traceability
Every merged/retrained model exposes its full chain — which base it came from, with which job and
dataset, and what it merged — via GET /models/{id}/lineage.
The chain survives renames because identity is the version_id, not the (mutable) name.
See also
- The Model Flywheel — the concept
- Flywheel Tutorial — end-to-end walkthrough
- Merge & Retrain API — full contract
- Model Catalog — all available models
Authors: José Luis Minich, Maximiliano Lucius.