Skip to content

Commit 4282a0e

Browse files
committed
feat: add ownedBy and createdAt for OpenModel
Signed-off-by: googs1025 <googs1025@gmail.com>
1 parent 5e00ed3 commit 4282a0e

10 files changed

Lines changed: 96 additions & 3 deletions

File tree

api/core/v1alpha1/model_types.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ const (
3737

3838
HUGGING_FACE = "Huggingface"
3939
MODEL_SCOPE = "ModelScope"
40+
41+
DefaultOwnedBy = "llmaz"
4042
)
4143

4244
// ModelHub represents the model registry for model downloads.
@@ -195,6 +197,18 @@ type ModelSpec struct {
195197
Source ModelSource `json:"source"`
196198
// InferenceConfig represents the inference configurations for the model.
197199
InferenceConfig *InferenceConfig `json:"inferenceConfig,omitempty"`
200+
// OwnedBy represents the owner of the running models serving by the backends,
201+
// which will be exported as the field of "OwnedBy" in openai-compatible API "/models".
202+
// Default to "llmaz" if not set.
203+
// +optional
204+
// +kubebuilder:default="llmaz"
205+
OwnedBy *string `json:"ownedBy,omitempty"`
206+
// CreatedAt represents the creation timestamp of the running models serving by the backends,
207+
// which will be exported as the field of "Created" in openai-compatible API "/models".
208+
// It follows the format of RFC 3339, for example "2024-05-21T10:00:00Z".
209+
// +optional
210+
// +kubebuilder:validation:Format=date-time
211+
CreatedAt *metav1.Time `json:"createdAt,omitempty"`
198212
}
199213

200214
const (

api/core/v1alpha1/zz_generated.deepcopy.go

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client-go/applyconfiguration/core/v1alpha1/modelspec.go

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/llmaz.io_openmodels.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ spec:
4141
spec:
4242
description: ModelSpec defines the desired state of Model
4343
properties:
44+
createdAt:
45+
description: |-
46+
CreatedAt represents the creation timestamp of the running models serving by the backends,
47+
which will be exported as the field of "Created" in openai-compatible API "/models".
48+
It follows the format of RFC 3339, for example "2024-05-21T10:00:00Z".
49+
format: date-time
50+
type: string
4451
familyName:
4552
description: |-
4653
FamilyName represents the model type, like llama2, which will be auto injected
@@ -106,6 +113,13 @@ spec:
106113
maxItems: 8
107114
type: array
108115
type: object
116+
ownedBy:
117+
default: llmaz
118+
description: |-
119+
OwnedBy represents the owner of the running models serving by the backends,
120+
which will be exported as the field of "OwnedBy" in openai-compatible API "/models".
121+
Default to "llmaz" if not set.
122+
type: string
109123
source:
110124
description: |-
111125
Source represents the source of the model, there're several ways to load

pkg/controller/core/model_controller.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package controller
1818

1919
import (
2020
"context"
21-
2221
"k8s.io/apimachinery/pkg/runtime"
2322
"k8s.io/apimachinery/pkg/types"
2423
"k8s.io/client-go/tools/record"

pkg/webhook/openmodel_webhook.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package webhook
1919
import (
2020
"context"
2121

22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2223
"k8s.io/apimachinery/pkg/runtime"
2324
"k8s.io/apimachinery/pkg/util/validation"
2425
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -59,6 +60,10 @@ func (w *OpenModelWebhook) Default(ctx context.Context, obj runtime.Object) erro
5960
model.Labels = map[string]string{}
6061
}
6162
model.Labels[coreapi.ModelFamilyNameLabelKey] = string(model.Spec.FamilyName)
63+
if model.Spec.CreatedAt == nil {
64+
now := metav1.Now()
65+
model.Spec.CreatedAt = &now
66+
}
6267
return nil
6368
}
6469

site/content/en/docs/reference/core.v1alpha1.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,24 @@ the model such as loading from huggingface, OCI registry, s3, host path and so o
361361
<p>InferenceConfig represents the inference configurations for the model.</p>
362362
</td>
363363
</tr>
364+
<tr><td><code>ownedBy</code><br/>
365+
<code>string</code>
366+
</td>
367+
<td>
368+
<p>OwnedBy represents the owner of the running models serving by the backends,
369+
which will be exported as the field of &quot;OwnedBy&quot; in openai-compatible API &quot;/models&quot;.
370+
Default to &quot;llmaz&quot; if not set.</p>
371+
</td>
372+
</tr>
373+
<tr><td><code>createdAt</code><br/>
374+
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#time-v1-meta"><code>k8s.io/apimachinery/pkg/apis/meta/v1.Time</code></a>
375+
</td>
376+
<td>
377+
<p>CreatedAt represents the creation timestamp of the running models serving by the backends,
378+
which will be exported as the field of &quot;Created&quot; in openai-compatible API &quot;/models&quot;.
379+
It follows the format of RFC 3339, for example &quot;2024-05-21T10:00:00Z&quot;.</p>
380+
</td>
381+
</tr>
364382
</tbody>
365383
</table>
366384

test/integration/webhook/model_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@ var _ = ginkgo.Describe("model default and validation", func() {
5555
return wrapper.MakeModel("llama3-8b").ModelSourceWithModelID("meta-llama/Meta-Llama-3-8B", "", "", nil, nil).FamilyName("llama3").Obj()
5656
},
5757
wantModel: func() *coreapi.OpenModel {
58-
return wrapper.MakeModel("llama3-8b").ModelSourceWithModelID("meta-llama/Meta-Llama-3-8B", "", "main", nil, nil).ModelSourceWithModelHub("Huggingface").FamilyName("llama3").Label(coreapi.ModelFamilyNameLabelKey, "llama3").Obj()
58+
return wrapper.MakeModel("llama3-8b").ModelSourceWithModelID("meta-llama/Meta-Llama-3-8B", "", "main", nil, nil).ModelSourceWithModelHub("Huggingface").FamilyName("llama3").Label(coreapi.ModelFamilyNameLabelKey, "llama3").OwnedBy(coreapi.DefaultOwnedBy).Obj()
5959
},
6060
}),
6161
ginkgo.Entry("apply modelscope model hub name", &testDefaultingCase{
6262
model: func() *coreapi.OpenModel {
6363
return wrapper.MakeModel("llama3-8b").FamilyName("llama3").ModelSourceWithModelHub("ModelScope").ModelSourceWithModelID("LLM-Research/Meta-Llama-3-8B", "", "", nil, nil).Obj()
6464
},
6565
wantModel: func() *coreapi.OpenModel {
66-
return wrapper.MakeModel("llama3-8b").ModelSourceWithModelID("LLM-Research/Meta-Llama-3-8B", "", "main", nil, nil).ModelSourceWithModelHub("ModelScope").FamilyName("llama3").Label(coreapi.ModelFamilyNameLabelKey, "llama3").Obj()
66+
return wrapper.MakeModel("llama3-8b").ModelSourceWithModelID("LLM-Research/Meta-Llama-3-8B", "", "main", nil, nil).ModelSourceWithModelHub("ModelScope").FamilyName("llama3").Label(coreapi.ModelFamilyNameLabelKey, "llama3").OwnedBy(coreapi.DefaultOwnedBy).Obj()
6767
},
6868
}),
6969
)

test/util/validation/validate_model.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package validation
1919
import (
2020
"context"
2121
"errors"
22+
"fmt"
2223

2324
"github.com/onsi/gomega"
2425
"k8s.io/apimachinery/pkg/types"
@@ -37,6 +38,15 @@ func ValidateModel(ctx context.Context, k8sClient client.Client, model *coreapi.
3738
if model.Labels[coreapi.ModelFamilyNameLabelKey] != string(model.Spec.FamilyName) {
3839
return errors.New("family name not right")
3940
}
41+
if model.Spec.OwnedBy == nil {
42+
return fmt.Errorf("ownedBy is nil")
43+
}
44+
if *model.Spec.OwnedBy != coreapi.DefaultOwnedBy {
45+
return fmt.Errorf("ownedBy value not right: expected %q, got %q", coreapi.DefaultOwnedBy, *model.Spec.OwnedBy)
46+
}
47+
if model.Spec.CreatedAt == nil {
48+
return fmt.Errorf("createdAt is nil")
49+
}
4050

4151
return nil
4252
}, util.IntegrationTimeout, util.Interval).Should(gomega.Succeed())

test/util/wrapper/model.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ func (w *ModelWrapper) Label(k, v string) *ModelWrapper {
107107
return w
108108
}
109109

110+
func (w *ModelWrapper) OwnedBy(ownedBy string) *ModelWrapper {
111+
w.Spec.OwnedBy = &ownedBy
112+
return w
113+
}
114+
110115
func MakeFlavor(name string) *FlavorWrapper {
111116
return &FlavorWrapper{
112117
coreapi.Flavor{

0 commit comments

Comments
 (0)