Skip to main content

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:

FieldMerge outputRetrain output
frameworktransformersinherited from the training template
precisionbf16 (never re-quantized)per the training template
base_model_version_idprimary input (adapter/source)the base it was retrained on
training_job_idthe 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"}]})
Lifecycle

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


Authors: José Luis Minich, Maximiliano Lucius.