lablup / lablup/backend.ai

[ModelDeploy] Runtime variants created through the API can never be deployed

Open Beginner friendly
#13,393 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
670
Forks
183
Avg merge
15h 13m
Merged PRs (30d)
368

Description

## Goal

The revision merge chain must always be able to produce a resolvable model definition, so a preset-driven deploy cannot fail for want of a field no layer supplies.

## Background

*Rewritten after investigation — the original framing ("validate presets and runtime variants at write time") did not survive contact with the code. See the closing note.*

`ModelConfig` requires both `name` and `model_path` (`common/config.py:323`). The lowest-priority draft in the merge chain, `_model_mount_path_default_draft` (`sokovan/deployment/revision_draft/reader.py:145`), supplied only `model_path`. Everything above it is optional, so `name` had to come from the runtime variant's `default_model_definition`, the preset, a vfolder yaml, or the request.

For a model-store deploy none of those apply except the variant baseline — and **that baseline is empty for every runtime variant created through the API**:

- `RuntimeVariantCreatorSpec.build_row()` hardcodes `default_model_definition = ModelDefinitionDraft()` (`repositories/runtime_variant/creators.py:35`).
- `RuntimeVariantUpdaterSpec` exposes only `name` and `description` (`repositories/runtime_variant/updaters.py`).
- The field appears on the response DTO and the GQL node, on no input anywhere.

Only the alembic seed (b5c6d7e8f9a0) writes real values, so the built-in variants work and every API-created one is permanently undeployable: `to_resolved()` raises at `deployment_controller.py:436`, after the endpoint row is already committed.

The fix is one layer down from the symptom: the baseline draft now supplies `name` as well as `model_path`, so the chain always resolves regardless of what the variant carries. Any higher layer still overrides it.

## Acceptance Criteria

- A revision built on a runtime variant with an empty `default_model_definition` resolves, and names the model `model`.
- A `name` supplied by the variant baseline, the preset, a vfolder yaml, or the request still wins over the default.
- No change to `model_path` resolution.

## Dropped from the original scope

**Preset resource-slot validation at write time.** #13392 makes a preset that omits a required slot fail cleanly with a good error and no leftover endpoint. Duplicating `RequiredResourceSlotRule` at preset-write time would mean giving the preset service a dependency on `resource_slot_types.required` for defence in depth of marginal value.

## Follow-up worth filing separately

`runtime_variants.default_model_definition` is not writable through any API. This change makes such variants deployable, but a custom variant still cannot ship its own baseline model definition — a genuine API gap, and a feature rather than a fix.

JIRA Issue: BA-XXXX

Contributor guide

Open the contributing guide

Research direction

Start with sokovan/deployment/revision_draft/reader.py:145 and trace the merge chain into common/config.py:323 and deployment_controller.py:436. Verify the empty-baseline case and check that higher-priority values from the variant, preset, vfolder YAML, or request continue to win; done means resolution succeeds with name model without changing model_path resolution.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.