Migrating to v1alpha2#
This guide maps v1alpha1 concepts to their v1alpha2 equivalents and provides conversion recipes for the common deployment patterns.
Note
Read the Legacy Overview first for coexistence rules and the migration/removal boundary.
Warning
This page maps fields and target shapes; it is not a migration execution or cleanup runbook. Install and verify the bridge first. The bounded administrator-run Plan/Apply behavior and manual outcomes are governed by ADR-0002.
Resource mapping#
v1alpha1 |
v1alpha2 |
Migration |
|---|---|---|
|
|
Templates → profiles, one profile per template profile. |
|
|
Same, cluster-scoped. |
|
|
Reference a profile instead of a template. |
|
|
Override shape changed (see below). |
|
|
Image-based services should onboard an explicit AIMModel. |
|
|
Inline on one model, or derived from a shared base-image model. |
|
|
Standalone derivation resource. |
|
|
Profile-copy is now first-class (groups derivedFrom + version + overrides). |
|
|
Sources live on each profile. |
|
|
Created automatically from |
Resource-by-resource walkthrough#
AIMService#
Before (v1alpha1):
apiVersion: aim.eai.amd.com/v1alpha1
kind: AIMService
metadata:
name: qwen-chat
spec:
model:
name: qwen-qwen3-32b
template:
selectionCriteria:
precision: fp8
acceleratorModel: MI300X
metric: latency
After (v1alpha2):
apiVersion: aim.eai.amd.com/v1alpha2
kind: AIMService
metadata:
name: qwen-chat
spec:
model:
name: qwen-qwen3-32b
profile:
selector:
precision: fp8
acceleratorModel: MI300X
metric: latency
The selector lives under spec.profile.selector (not spec.template.selectionCriteria). The same field names are reused — precision, acceleratorModel, acceleratorCount, metric, engine, type.
For services that reference a template by name:
Before:
spec:
template:
name: qwen-qwen3-32b-mi300x-fp8-latency
After:
spec:
profile:
name: qwen-qwen3-32b-mi300x-fp8-latency
The profile names produced by v1alpha2 discovery match the v1alpha1 template profile names in most cases.
AIMService.spec.overrides → AIMService.spec.profileOverrides#
The override shape changes substantively in v1alpha2:
v1alpha1 ( |
v1alpha2 ( |
|---|---|
Flat |
Structured |
Modifies template selection in place |
Materialises a service-owned overlay AIMProfile |
No effect on cache key |
Participates in cache-key computation |
Before:
spec:
template:
name: qwen-qwen3-32b-mi300x-fp8-latency
overrides:
engineArgs:
max-model-len: "32768"
After:
spec:
profile:
name: qwen-qwen3-32b-mi300x-fp8-latency
profileOverrides:
engineArgs:
max-model-len: 32768
Notice the JSON value is now a typed integer rather than a string — engineArgs accepts typed JSON in v1alpha2.
Custom models#
The v1alpha2 custom-model flow selects base definitions and overrides identity and weights. This example uses a shared base-image model:
Before (v1alpha1):
apiVersion: aim.eai.amd.com/v1alpha1
kind: AIMModel
metadata:
name: acme-transformer
spec:
aimId: acme/custom-transformer
custom:
image: amdenterpriseai/aim-base:0.8.5
modelSources:
- modelId: acme/custom-transformer
sourceUri: s3://acme-models/custom-transformer
customTemplates:
- name: acme-transformer-mi300x-fp16
acceleratorModel: MI300X
acceleratorType: gpu
acceleratorCount: 1
precision: fp16
metric: throughput
engine: vllm
After (v1alpha2):
apiVersion: aim.eai.amd.com/v1alpha2
kind: AIMModel
metadata:
name: aim-base-vllm
spec:
image: amdenterpriseai/aim-base:0.11
---
apiVersion: aim.eai.amd.com/v1alpha2
kind: AIMModel
metadata:
name: acme-transformer
spec:
profiles:
derivedFrom:
selector:
role: base
modelRef:
name: aim-base-vllm
versionPolicy: all
overrides:
aimId: acme/custom-transformer
modelId: acme/custom-transformer
modelSources:
- modelId: acme/custom-transformer
sourceUri: s3://acme-models/custom-transformer
The base-image AIMModel publishes all base definitions, including those without materialised profiles. A separate custom-model AIMModel selects those definitions and supplies target identity and weights.
See Custom Models for the full walkthrough.
Fine-tunes#
v1alpha1 had no first-class fine-tune flow — you’d either fork an AIMServiceTemplate and edit its model sources, or use AIMService.spec.overrides. v1alpha2 makes fine-tunes a discrete AIMModel:
apiVersion: aim.eai.amd.com/v1alpha2
kind: AIMModel
metadata:
name: qwen-finetune-acme
spec:
profiles:
derivedFrom:
selector:
aimId: qwen/qwen3-32b
versionPolicy: pinned
version: "0.8.5"
overrides:
modelSources:
- modelId: acme/qwen3-32b-finetune
sourceUri: hf://acme/qwen3-32b-finetune
See Fine-Tuned Models for the full walkthrough.
AIMServiceTemplate → AIMProfile#
Hand-authored v1alpha1 service templates become AIMProfile resources. The fields map almost 1:1:
Before (v1alpha1):
apiVersion: aim.eai.amd.com/v1alpha1
kind: AIMServiceTemplate
metadata:
name: qwen3-32b-throughput
namespace: ml-team
spec:
modelName: qwen-qwen3-32b
acceleratorModel: MI300X
acceleratorType: gpu
acceleratorCount: 1
precision: fp8
metric: throughput
engine: vllm
engineArgs:
gpu-memory-utilization: "0.95"
After (v1alpha2):
apiVersion: aim.eai.amd.com/v1alpha2
kind: AIMProfile
metadata:
name: qwen3-32b-throughput
namespace: ml-team
spec:
aimId: qwen/qwen3-32b
modelId: qwen/qwen3-32b-fp8
acceleratorModel: MI300X
acceleratorType: gpu
acceleratorCount: 1
precision: fp8
metric: throughput
engine: vllm
image: amdenterpriseai/aim-qwen-qwen3-32b:0.8.5
engineArgs:
gpu-memory-utilization: "0.95"
modelSources:
- modelId: qwen/qwen3-32b-fp8
sourceUri: hf://qwen/qwen3-32b-fp8
Differences:
modelNameis gone — profiles aren’t tied to a model name; they declareaimIdandmodelIddirectly.imageis now required on the profile (templates inherited it from the parent model via discovery).modelSourceslives on the profile (templates inherited them from the parent model).
The simpler path: re-create the model through v1alpha2 discovery and let the controller produce the equivalent profiles. Hand-authoring profiles is only necessary when you can’t run discovery.
AIMTemplateCache → AIMProfileCache#
You don’t typically apply AIMProfileCache directly. It’s created automatically by the AIMService controller when spec.caching is enabled (or by AIMProfile.spec.caching.enabled for namespace-scoped profiles).
For pre-warming a model independent of any service:
Before (v1alpha1):
apiVersion: aim.eai.amd.com/v1alpha1
kind: AIMTemplateCache
metadata:
name: qwen-cache
spec:
templateName: qwen-qwen3-32b-mi300x-fp8-latency
After (v1alpha2):
Set spec.caching.enabled: true on the corresponding namespace AIMProfile. The controller then provisions an AIMProfileCache automatically:
apiVersion: aim.eai.amd.com/v1alpha2
kind: AIMProfile
metadata:
name: qwen-qwen3-32b-mi300x-fp8-latency
namespace: ml-team
spec:
# ... profile spec ...
caching:
enabled: true
Cluster-scoped profiles cannot enable caching directly (cluster-scoped caches not yet implemented).
Migration order#
Install the bridge CRDs before the matching operator and verify predecessor serving before planning any changes. Use ADR-0002 for operation ordering, dry-run, partial-failure recovery, and manual outcomes. These field mappings do not authorize template/cache deletion, storage rewriting, or automatic handling of custom and ambiguous resources.
Validation traps#
The v1alpha2 CRD rejects legacy-only fields and invalid combinations of the onboarding spec shapes:
Rejected on v1alpha2 |
Resource |
Why |
|---|---|---|
|
|
Lives on |
|
|
Replaced by base-image + |
|
|
Replaced by |
|
|
Replaced by |
Flat |
|
Use |
|
|
Generated onboarding is separate from image discovery and profile derivation. |
None of |
|
Exactly one onboarding flow is required. |
|
|
External derivation requires a source selector or alternate catalog. |
|
|
Inline profiles select from the model’s own image. |
|
|
These fields configure generated model-ID onboarding only. |
|
|
Derivation identity and runtime come from the selected source profiles and overrides. |
Image-discovery/runtime fields such as |
|
Configure the generated profile runtime on the referenced RuntimeConfig fallback. |
|
|
Use |
|
|
Use |
|
|
Overlay requires a named seed. |
|
|
Services always resolve to deployable profiles. |
|
|
Resolver needs an anchor for watch fan-out. |
If admission rejects a v1alpha1 manifest, the error message is targeted — it names the field and the v1alpha2 equivalent.
After migration#
Once a workload is migrated:
kubectl get aimservice <name>shows the resolved profile in the printcolumn output (priority 1).status.resolvedProfilecarries the chosenAIMProfilereference.The KServe
InferenceServiceis named<service-name>(unchanged from v1alpha1) — your downstream consumers don’t need to update endpoints.