feat(gallery): support ConfigURLs (#2012)

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
Ettore Di Giacinto 2024-04-12 00:49:23 +02:00 committed by GitHub
parent da82ce81b5
commit b2785ff06e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 40 additions and 4 deletions

View File

@ -43,6 +43,7 @@ Can you help rephrasing sentences?
type modelApplyRequest struct { type modelApplyRequest struct {
ID string `json:"id"` ID string `json:"id"`
URL string `json:"url"` URL string `json:"url"`
ConfigURL string `json:"config_url"`
Name string `json:"name"` Name string `json:"name"`
Overrides map[string]interface{} `json:"overrides"` Overrides map[string]interface{} `json:"overrides"`
} }
@ -366,6 +367,29 @@ var _ = Describe("API test", func() {
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(content["backend"]).To(Equal("llama")) Expect(content["backend"]).To(Equal("llama"))
}) })
It("apply models from config", func() {
response := postModelApplyRequest("http://127.0.0.1:9090/models/apply", modelApplyRequest{
ConfigURL: "https://raw.githubusercontent.com/mudler/LocalAI/master/embedded/models/hermes-2-pro-mistral.yaml",
})
Expect(response["uuid"]).ToNot(BeEmpty(), fmt.Sprint(response))
uuid := response["uuid"].(string)
Eventually(func() bool {
response := getModelStatus("http://127.0.0.1:9090/models/jobs/" + uuid)
return response["processed"].(bool)
}, "360s", "10s").Should(Equal(true))
Eventually(func() []string {
models, _ := client.ListModels(context.TODO())
modelList := []string{}
for _, m := range models.Models {
modelList = append(modelList, m.ID)
}
return modelList
}, "360s", "10s").Should(ContainElements("hermes-2-pro-mistral"))
})
It("apply models without overrides", func() { It("apply models without overrides", func() {
response := postModelApplyRequest("http://127.0.0.1:9090/models/apply", modelApplyRequest{ response := postModelApplyRequest("http://127.0.0.1:9090/models/apply", modelApplyRequest{
URL: "https://raw.githubusercontent.com/go-skynet/model-gallery/main/bert-embeddings.yaml", URL: "https://raw.githubusercontent.com/go-skynet/model-gallery/main/bert-embeddings.yaml",

View File

@ -19,7 +19,8 @@ type ModelGalleryEndpointService struct {
} }
type GalleryModel struct { type GalleryModel struct {
ID string `json:"id"` ID string `json:"id"`
ConfigURL string `json:"config_url"`
gallery.GalleryModel gallery.GalleryModel
} }
@ -64,6 +65,7 @@ func (mgs *ModelGalleryEndpointService) ApplyModelGalleryEndpoint() func(c *fibe
Id: uuid.String(), Id: uuid.String(),
GalleryName: input.ID, GalleryName: input.ID,
Galleries: mgs.galleries, Galleries: mgs.galleries,
ConfigURL: input.ConfigURL,
} }
return c.JSON(struct { return c.JSON(struct {
ID string `json:"uuid"` ID string `json:"uuid"`

View File

@ -9,6 +9,7 @@ import (
"github.com/go-skynet/LocalAI/core/config" "github.com/go-skynet/LocalAI/core/config"
"github.com/go-skynet/LocalAI/pkg/gallery" "github.com/go-skynet/LocalAI/pkg/gallery"
"github.com/go-skynet/LocalAI/pkg/startup"
"github.com/go-skynet/LocalAI/pkg/utils" "github.com/go-skynet/LocalAI/pkg/utils"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
@ -90,6 +91,9 @@ func (g *GalleryService) Start(c context.Context, cl *config.BackendConfigLoader
} else { } else {
err = gallery.InstallModelFromGalleryByName(op.Galleries, op.GalleryName, g.modelPath, op.Req, progressCallback) err = gallery.InstallModelFromGalleryByName(op.Galleries, op.GalleryName, g.modelPath, op.Req, progressCallback)
} }
} else if op.ConfigURL != "" {
startup.PreloadModelsConfigurations(op.ConfigURL, g.modelPath, op.ConfigURL)
err = cl.Preload(g.modelPath)
} else { } else {
err = prepareModel(g.modelPath, op.Req, cl, progressCallback) err = prepareModel(g.modelPath, op.Req, cl, progressCallback)
} }
@ -129,6 +133,7 @@ func processRequests(modelPath, s string, cm *config.BackendConfigLoader, galler
utils.ResetDownloadTimers() utils.ResetDownloadTimers()
if r.ID == "" { if r.ID == "" {
err = prepareModel(modelPath, r.GalleryModel, cm, utils.DisplayDownloadFunction) err = prepareModel(modelPath, r.GalleryModel, cm, utils.DisplayDownloadFunction)
} else { } else {
if strings.Contains(r.ID, "@") { if strings.Contains(r.ID, "@") {
err = gallery.InstallModelFromGallery( err = gallery.InstallModelFromGallery(

View File

@ -146,12 +146,16 @@ In the body of the request you must specify the model configuration file URL (`u
```bash ```bash
LOCALAI=http://localhost:8080 LOCALAI=http://localhost:8080
curl $LOCALAI/models/apply -H "Content-Type: application/json" -d '{ curl $LOCALAI/models/apply -H "Content-Type: application/json" -d '{
"url": "<MODEL_CONFIG_FILE>" "config_url": "<MODEL_CONFIG_FILE_URL>"
}' }'
# or if from a repository # or if from a repository
curl $LOCALAI/models/apply -H "Content-Type: application/json" -d '{ curl $LOCALAI/models/apply -H "Content-Type: application/json" -d '{
"id": "<GALLERY>@<MODEL_NAME>" "id": "<GALLERY>@<MODEL_NAME>"
}' }'
# or from a gallery config
curl $LOCALAI/models/apply -H "Content-Type: application/json" -d '{
"url": "<MODEL_CONFIG_FILE_URL>"
}'
``` ```
An example that installs openllama can be: An example that installs openllama can be:
@ -159,7 +163,7 @@ An example that installs openllama can be:
```bash ```bash
LOCALAI=http://localhost:8080 LOCALAI=http://localhost:8080
curl $LOCALAI/models/apply -H "Content-Type: application/json" -d '{ curl $LOCALAI/models/apply -H "Content-Type: application/json" -d '{
"url": "https://github.com/go-skynet/model-gallery/blob/main/openllama_3b.yaml" "config_url": "https://raw.githubusercontent.com/mudler/LocalAI/master/embedded/models/hermes-2-pro-mistral.yaml"
}' }'
``` ```

View File

@ -5,6 +5,7 @@ type GalleryOp struct {
Id string Id string
Galleries []Gallery Galleries []Gallery
GalleryName string GalleryName string
ConfigURL string
} }
type GalleryOpStatus struct { type GalleryOpStatus struct {