From ed9b2e8c1c41592e85bc40972fd6083c18cf6df5 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 15 Oct 2026 22:43:04 +0000 Subject: [PATCH] =?UTF-8?q?Lot=2025=20:=20Strata=20tenu=20par=20la=20fa?= =?UTF-8?q?=C3=A7ade=20(LOKI=5FSTRATA=3Drust)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port de backend_strata.go (rust/loki-rs/src/strata) : la machine (cartes par nvidia-smi, Python 3.10+ et venv, RAM totale et disponible, RAM du moteur Strata en marche, place libre), ce qui y tient et la recommandation, la configuration de lancement en clair des modèles installés (placement des experts drop/ram/arena/disk, carte d'aide, réglages du preset), les réglages d'un modèle installé et l'installation (job des moteurs : paquet figé vérifié par SHA-256, installeur lancé et journalisé comme le sinkWriter du Go, preset écrit puis activé par le Go). Tenu seulement avec LOKI_BACKENDS=rust ; le lancement (loki serve) reste au Go, qui relaie les routes du tunnel. Correction du Go : /api/strata/settings décidait « en service » après avoir écrit les nouveaux réglages, donc jamais pour un réglage changé ; décidé désormais avant l'écriture, comme SavePresetApplying. Le port suit. Parité : parity_strata_test.go (crochets de test : release, meminfo, place libre, action de service) tire du Go un journal rejoué par tests/strata.rs ; les tests du Go portés dans strata/tests.rs ; TestFacadeStrata côté Go. Mutations : 71 tuées sur 71. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv --- README.md | 1 + ...0-15-rust-migration-lot25-strata-design.md | 121 + internal/loki/backend_strata.go | 48 +- internal/loki/facade_chat.go | 4 +- internal/loki/facade_strata.go | 28 + internal/loki/facade_strata_test.go | 67 + internal/loki/parity_strata_test.go | 464 ++ internal/loki/sys_platform_unix.go | 2 +- internal/loki/sys_service.go | 6 +- rust/loki-rs/src/api.rs | 4 + rust/loki-rs/src/lib.rs | 1 + rust/loki-rs/src/main.rs | 14 + rust/loki-rs/src/presets_api.rs | 2 +- rust/loki-rs/src/proxy.rs | 9 + rust/loki-rs/src/strata/api.rs | 926 +++ rust/loki-rs/src/strata/mod.rs | 848 +++ rust/loki-rs/src/strata/tests.rs | 485 ++ rust/loki-rs/tests/common/fakego.rs | 2 + rust/loki-rs/tests/lot2.rs | 1 + rust/loki-rs/tests/parity_strata/strata.json | 5708 +++++++++++++++++ rust/loki-rs/tests/proxy.rs | 1 + rust/loki-rs/tests/strata.rs | 356 + 22 files changed, 9079 insertions(+), 19 deletions(-) create mode 100644 docs/superpowers/specs/2026-10-15-rust-migration-lot25-strata-design.md create mode 100644 internal/loki/facade_strata.go create mode 100644 internal/loki/facade_strata_test.go create mode 100644 internal/loki/parity_strata_test.go create mode 100644 rust/loki-rs/src/strata/api.rs create mode 100644 rust/loki-rs/src/strata/mod.rs create mode 100644 rust/loki-rs/src/strata/tests.rs create mode 100644 rust/loki-rs/tests/parity_strata/strata.json create mode 100644 rust/loki-rs/tests/strata.rs diff --git a/README.md b/README.md index d368728..90ba795 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,7 @@ redémarrages (volume `/data`). Variables d'environnement du conteneur : | `LOKI_UPDATE` | `rust` : la mise à jour de Loki (`/api/update`, `/api/update/apply`) est servie par la façade Rust ; en conteneur, l'image se met à jour par Docker (expérimental, migration en cours) | Go | | `LOKI_MCP` | `rust` : les serveurs MCP — configuration, catalogue, état, pool de sessions stdio et HTTP — sont tenus par la façade Rust ; le Go lui demande les outils MCP de l'agent et leurs appels (expérimental, migration en cours) | Go | | `LOKI_BACKENDS` | `rust` : les backends llama.cpp — statut, vérification git, binaires précompilés, bascule fast/opt, backends custom, GPU vus par un moteur — et le job des moteurs sont tenus par la façade Rust ; les jobs du Go (compilation, moteur de l'image, Strata) lui rapportent leurs étapes (expérimental, migration en cours) | Go | +| `LOKI_STRATA` | `rust` (avec `LOKI_BACKENDS=rust`) : l'écran de Strata — machine, ce qui y tient, recommandation, modèles installés —, ses réglages et son installation sont tenus par la façade Rust ; le lancement reste au Go (expérimental, migration en cours) | Go | | `LOKI_ENGINE_IMAGE` | `rust` (avec `LOKI_BACKENDS=rust`) : le panneau « moteur de l'image » — version qui tourne, dernier build publié, version recommandée, mise à jour depuis le registre officiel avec essai à blanc, bascules, retour à la version précédente, vérification du rendu du gabarit — est tenu par la façade Rust (expérimental, migration en cours) | Go | | `LOKI_PROJECTS` | `rust` : le hub des projets (liste et comptes, création, renommage, description, suppression, bascule) est tenu par la façade Rust ; les discussions restent à qui tient la conversation (expérimental, migration en cours) | Go | | `LOKI_SYSTEM` | `rust` : les interrupteurs système — accès internet et Crawl4AI, pilotage du navigateur, clé de complétion, écoute réseau du moteur — sont tenus par la façade Rust ; le navigateur piloté reste au Go (expérimental, migration en cours) | Go | diff --git a/docs/superpowers/specs/2026-10-15-rust-migration-lot25-strata-design.md b/docs/superpowers/specs/2026-10-15-rust-migration-lot25-strata-design.md new file mode 100644 index 0000000..e77ed51 --- /dev/null +++ b/docs/superpowers/specs/2026-10-15-rust-migration-lot25-strata-design.md @@ -0,0 +1,121 @@ +# Lot 25 — Strata tenu par la façade + +## Contexte + +Strata est le deuxième moteur de Loki. Il répartit les experts d'un MoE de +125 B (famille Qwen3.8-Flash-Next) entre VRAM, RAM et disque. Le moteur est +le paquet **figé** publié par AJEAN : les sources et le binaire Linux CUDA 12, +vérifiés par SHA-256. Un preset le choisit (`ENGINE=strata`). + +`backend_strata.go` sert trois routes : + +- `/api/strata` : la machine (cartes, RAM, disque, Python), ce qui y tient, + la recommandation par version et les modèles installés, avec leur + configuration de lancement en clair ; +- `/api/strata/settings` : les réglages d'un modèle installé. S'il est en + service, la configuration est réappliquée et le moteur relancé ; +- `/api/strata/install` : un job des moteurs. Il télécharge et vérifie le + paquet, lance l'installeur de Strata, écrit le preset et bascule dessus. + +Le lancement (`loki serve` d'un preset Strata) vit aussi dans ce fichier. + +## Le lot + +Avec `LOKI_STRATA=rust` **et** `LOKI_BACKENDS=rust` (expérimental), la façade +(`rust/loki-rs/src/strata`) sert les trois routes : + +- **la décision pure** (`strata/mod.rs`) : + - placement des experts : drop, ram, arena ou disk, selon la RAM + disponible, la carte d'appoint et `experts.bin` ; + - configuration de lancement : réglages validés, carte d'aide, mode des + experts, réglages du preset ; + - ce qui tient sur la machine, la recommandation, les réglages, les noms ; +- **la machine** (`strata/api.rs`) : + - cartes via `nvidia-smi` (la sonde des backends) ; + - Python 3.10+ et son module venv ; + - RAM totale et disponible (`/proc/meminfo`) ; + - RAM du moteur Strata en marche (arbre du service dans `/proc`) ; + - place libre ; +- **l'installation** : le job des moteurs. La sortie de l'installeur est + découpée en lignes comme le `sinkWriter` du Go : une barre `\r` n'est + montrée que toutes les 10 s. La bascule finale passe par le Go + (`/internal/v1/preset/apply`, mode `switch`), qui applique le preset et + relance le service. + +Sans les backends, loki-rs ne passe pas la variable au Go et Strata reste au +Go. Le lancement reste au Go (`loki serve`, que `loki-rs engine serve` lui +délègue pour un preset Strata). + +Côté Go, `facade_strata.go` relaie à la façade les routes reçues par le +tunnel. + +## Correction du Go + +`/api/strata/settings` décidait si le preset était en service **après** y +avoir écrit les nouveaux réglages. L'empreinte du nouveau contenu ne +correspondait alors plus à la configuration active : changer un réglage du +modèle en service ne l'appliquait jamais, et le moteur n'était pas relancé. +« En service » se décide désormais avant l'écriture, comme dans +`SavePresetApplying`. Le port Rust suit. + +## Parité + +`internal/loki/parity_strata_test.go` (Linux x86_64) tire du Go un journal +rejoué par `tests/strata.rs`. Pour le tirer, le Go reçoit des crochets de +test : `strataReleaseBase` (variable), `meminfoPath`, `strataDiskFree` et +`serviceActionOSFn`. Le journal couvre : + +- **la machine** : + - sans carte, nvidia-smi en panne ou vide, carte trop ancienne ou trop + petite, carte d'aide trop ancienne ; + - trois cartes de même VRAM : la plus récente devant (capacité de calcul + arrondie au dixième) ; + - Python absent, en panne, illisible, trop ancien, sans venv ; + - 16, 47 ou 64 Go de RAM, meminfo sans MemAvailable ; + - disque presque plein ou juste trop petit (marge de 5 Go), données déjà + présentes ; +- **les réglages** : + - GET, corps illisible, preset vide ou avec chemin, preset absent ou + llama.cpp ; + - hors limites, experts inconnus ; + - preset inactif ; preset actif (appliqué et relancé), et pendant une + optimisation ; +- **l'installation** : + - GET, corps illisible, quant inconnu, optimisation en cours ; + - machine sans carte, modèle qui ne tient pas ; + - release introuvable, moteur altéré (empreinte) ; + - installation complète, puis réinstallation (sources déjà là et + décompressées, moteur téléchargé périmé retéléchargé) ; + - installeur en échec, installeur sans configuration ; +- **les modèles installés** : + - détails de lancement du modèle actif et de modèles inactifs (experts + sur disque ou en RAM, vision coupée, sans carte d'aide) ; + - mode du dernier lancement ; + - `experts.bin` avec le moteur du paquet ou d'un autre paquet ; + - RAM juste sous ou au-dessus du seuil du mode hors RAM, mode hors RAM + coupé dans le preset ; + - configuration de lancement disparue ou illisible ; +- **après chaque appel** : les actions du service, les clés de la + configuration et l'arborescence de `presets/` et `strata/` (sans le + contenu des archives). + +Autres tests : + +- les tests du Go (`backend_strata_test.go`), portés (`strata/tests.rs`) : + configuration de lancement, placement des experts, recommandation, + réglages, noms ; +- la RAM du moteur en marche, le découpage en lignes et les nombres écrits + à la Go ; +- le Go (`TestFacadeStrata`) : les trois routes partent à la façade, et + elles seules. + +## Mutations + +71 mutations du port Rust, toutes tuées (les dix survivantes du premier +passage l'ont été par les étapes et les tests ajoutés ci-dessus). + +## Écarts assumés + +- Les erreurs réseau (release injoignable) gardent le texte de `reqwest`. +- Une copie du moteur qui échoue (`prebuilt/`) ne donne pas exactement le + message du Go, qui ouvre la source puis la destination. diff --git a/internal/loki/backend_strata.go b/internal/loki/backend_strata.go index b25feff..ec1c145 100644 --- a/internal/loki/backend_strata.go +++ b/internal/loki/backend_strata.go @@ -52,13 +52,23 @@ import ( // autre paquet est remplacé au lancement (strataEnsureEngine). const ( strataVersion = "1.0" - strataReleaseBase = "https://github.com/nathaninline/ajean/releases/download/moe-v" + strataVersion + "/" strataSrcAsset = "ajean-moe-src-" + strataVersion + ".tar.gz" strataEngineAsset = "ajean-moe-engine-" + strataVersion + "-linux-x64-cuda12.zip" // strataEngineLocal : le nom sous lequel l'installeur attend le moteur (CUDA12_ASSET). strataEngineLocal = "strata-linux-x64-cuda12.zip" ) +// strataReleaseBase : la release figée. Une variable pour que les tests la +// pointent sur un faux serveur. +var strataReleaseBase = "https://github.com/nathaninline/ajean/releases/download/moe-v" + strataVersion + "/" + +// meminfoPath, strataDiskFree : la RAM et la place libre lues sur la machine, +// remplaçables par les tests (journal de parité de Strata). +var ( + meminfoPath = "/proc/meminfo" + strataDiskFree = diskFree +) + // strataAssetSHA : empreintes des fichiers de la release, vérifiées avant usage. var strataAssetSHA = map[string]string{ strataSrcAsset: "5747f69426973d957e4f9894a8e3333c6ef0d6ac8565e26ddb8d36f52211cb3b", @@ -154,7 +164,7 @@ const ( // memAvailableGB : la RAM réellement disponible (MemAvailable : libre + cache // récupérable), en Go. Hors Linux ou illisible : la RAM totale. func memAvailableGB() float64 { - b, err := os.ReadFile("/proc/meminfo") + b, err := os.ReadFile(meminfoPath) if err != nil { return totalRAMGB() } @@ -286,7 +296,7 @@ func strataDetect() strataEnv { env.AvailGB = min(memAvailableGB()+strataEngineRSSGB(), env.RAMGB) // strataHome() et pas LokiHome() : /data/strata peut être un disque à part // (SSD dédié monté dans le conteneur), c'est sa place libre qui compte. - if f := diskFree(strataHome()); f > 0 { + if f := strataDiskFree(strataHome()); f > 0 { env.DiskFreeGB = float64(f) / 1e9 } if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { @@ -1380,25 +1390,33 @@ func handleStrataSettings(w http.ResponseWriter, r *http.Request) { sendJSON(w, 400, map[string]any{"ok": false, "error": err.Error()}) return } + // « Actif » se décide AVANT l'écriture (comme SavePresetApplying) : c'est + // l'ancien contenu qui porte l'empreinte de la configuration courante. Lu + // après, un réglage changé faisait passer le preset en service pour + // inactif, et rien n'était appliqué. + active := false + if list, err := ListPresets(); err == nil { + for _, p := range list { + if p.ID == req.Preset && p.Active { + active = true + } + } + } path := filepath.Join(presetsDir(), req.Preset+".env") if err := os.WriteFile(path, []byte(next), 0o644); err != nil { sendJSON(w, 500, map[string]any{"ok": false, "error": err.Error()}) return } restarted := false - if list, err := ListPresets(); err == nil { - for _, p := range list { - if p.ID == req.Preset && p.Active { - if tuneDenyHTTP(w) { - return - } - if err := SwitchToPreset(path); err != nil { - sendJSON(w, 500, map[string]any{"ok": false, "error": err.Error()}) - return - } - restarted = true - } + if active { + if tuneDenyHTTP(w) { + return } + if err := SwitchToPreset(path); err != nil { + sendJSON(w, 500, map[string]any{"ok": false, "error": err.Error()}) + return + } + restarted = true } sendJSON(w, 200, map[string]any{"ok": true, "restarted": restarted}) } diff --git a/internal/loki/facade_chat.go b/internal/loki/facade_chat.go index da43af6..18dfd82 100644 --- a/internal/loki/facade_chat.go +++ b/internal/loki/facade_chat.go @@ -142,7 +142,7 @@ var facadeChatRoutes = map[string]bool{ // moteur (facade_engine.go), les interrupteurs système (facade_system.go), les // projets (facade_projects.go), les serveurs MCP (facade_mcp.go), la mise à // jour (facade_update.go), les backends llama.cpp (facade_backends.go), le -// moteur de l'image (facade_engineimg.go). +// moteur de l'image (facade_engineimg.go), Strata (facade_strata.go). // Posé APRÈS requireWebAuth : seule une requête authentifiée ici part, avec le // jeton interne qui en tient lieu là-bas. func withFacadeChat(path string, h http.HandlerFunc) http.HandlerFunc { @@ -177,6 +177,8 @@ func withFacadeChat(path string, h http.HandlerFunc) http.HandlerFunc { held, unavailable = facadeBackends, "moteurs indisponibles : " case facadeEngineImageRoutes[path]: held, unavailable = facadeEngineImage, "moteur de l'image indisponible : " + case facadeStrataRoutes[path]: + held, unavailable = facadeStrata, "Strata indisponible : " default: return h } diff --git a/internal/loki/facade_strata.go b/internal/loki/facade_strata.go new file mode 100644 index 0000000..bba41f4 --- /dev/null +++ b/internal/loki/facade_strata.go @@ -0,0 +1,28 @@ +package loki + +import ( + "os" + "strings" +) + +// facade_strata.go — Strata tenu par la façade Rust (LOKI_STRATA=rust, lot 25 +// de la migration ; expérimental, le Go reste le défaut) : la machine et ce +// qui y tient, les réglages d'un modèle installé et l'installation (job des +// moteurs, tenu par la façade avec LOKI_BACKENDS=rust) — +// rust/loki-rs/src/strata. loki-rs ne passe la variable qu'avec les backends. +// Le lancement (`loki serve` d'un preset ENGINE=strata) reste ici. + +const facadeStrataEnv = "LOKI_STRATA" + +// facadeStrata : la façade tient-elle Strata ? +func facadeStrata() bool { + return strings.EqualFold(strings.TrimSpace(os.Getenv(facadeStrataEnv)), "rust") && + facadeAddr() != "" && internalToken() != "" +} + +// facadeStrataRoutes : les routes que la façade sert alors. +var facadeStrataRoutes = map[string]bool{ + "/api/strata": true, + "/api/strata/install": true, + "/api/strata/settings": true, +} diff --git a/internal/loki/facade_strata_test.go b/internal/loki/facade_strata_test.go new file mode 100644 index 0000000..09ccb8e --- /dev/null +++ b/internal/loki/facade_strata_test.go @@ -0,0 +1,67 @@ +package loki + +import ( + "io" + "net/http" + "net/http/httptest" + "strings" + "sync" + "testing" +) + +// Strata part à la façade avec LOKI_STRATA=rust (lot 25) ; le reste du +// moteur, non. +func TestFacadeStrata(t *testing.T) { + testHome(t) + var mu sync.Mutex + var calls []string + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get(internalTokenHeader) != jetonTest { + w.WriteHeader(403) + return + } + mu.Lock() + calls = append(calls, r.Method+" "+r.URL.Path) + mu.Unlock() + io.WriteString(w, `{"ok":true,"de":"facade"}`) + })) + defer srv.Close() + t.Setenv(internalTokenEnv, jetonTest) + t.Setenv(facadeAddrEnv, strings.TrimPrefix(srv.URL, "http://")) + local := func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "go") } + + t.Setenv(facadeStrataEnv, "") + for p := range facadeStrataRoutes { + w := httptest.NewRecorder() + withFacadeChat(p, local)(w, httptest.NewRequest("POST", p, strings.NewReader("{}"))) + if w.Body.String() != "go" { + t.Fatalf("sans LOKI_STRATA, %s : %q", p, w.Body.String()) + } + } + t.Setenv(facadeStrataEnv, " RUST") + if len(facadeStrataRoutes) != 3 { + t.Fatalf("routes : %v", facadeStrataRoutes) + } + for p := range facadeStrataRoutes { + w := httptest.NewRecorder() + withFacadeChat(p, local)(w, httptest.NewRequest("POST", p, strings.NewReader("{}"))) + if !strings.Contains(w.Body.String(), "facade") { + t.Fatalf("%s non relayé : %q", p, w.Body.String()) + } + } + mu.Lock() + n := len(calls) + mu.Unlock() + if n != len(facadeStrataRoutes) { + t.Fatalf("relais : %v", calls) + } + w := httptest.NewRecorder() + withFacadeChat("/api/llamacpp/install", local)(w, httptest.NewRequest("POST", "/api/llamacpp/install", nil)) + if w.Body.String() != "go" { + t.Fatalf("la compilation reste au Go : %q", w.Body.String()) + } + t.Setenv(internalTokenEnv, "") + if facadeStrata() { + t.Fatal("tenu sans jeton interne") + } +} diff --git a/internal/loki/parity_strata_test.go b/internal/loki/parity_strata_test.go new file mode 100644 index 0000000..e84c310 --- /dev/null +++ b/internal/loki/parity_strata_test.go @@ -0,0 +1,464 @@ +//go:build linux + +package loki + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "io/fs" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "path/filepath" + "runtime" + "sort" + "strings" + "sync" + "testing" + "time" +) + +// parity_strata_test.go — journal de référence de Strata (lot 25 de la +// migration Rust) : la machine vue par l'écran d'installation (cartes, +// Python, RAM, disque) et ce qui y tient, les réglages d'un modèle installé +// (et la bascule qui les applique), l'installation (paquet figé vérifié, +// installeur lancé, preset écrit puis activé) et ses échecs. +// Rangé dans rust/loki-rs/tests/parity_strata/strata.json ; tests/strata.rs +// le rejoue par la façade. +// +// LOKI_PARITY_UPDATE=1 go test ./internal/loki -run TestPariteStrata + +const parityStrataFile = "../../rust/loki-rs/tests/parity_strata/strata.json" + +// Ce que sert la fausse release : les sources (archive), le moteur (des +// octets), un statut imposé, des empreintes attendues fausses. +type parityStrataRel struct { + Status int `json:"status,omitempty"` + Src []parityArchEntry `json:"src"` + Engine string `json:"engine"` + BadSHA bool `json:"bad_sha,omitempty"` +} + +type parityStrataStep struct { + Name string `json:"name"` + Machine string `json:"machine,omitempty"` + Meminfo string `json:"meminfo,omitempty"` + DiskFree int64 `json:"disk_free,omitempty"` + Files map[string]string `json:"files,omitempty"` + Config map[string]string `json:"config,omitempty"` + State map[string]string `json:"state,omitempty"` + Release *parityStrataRel `json:"release,omitempty"` + Tune bool `json:"tune,omitempty"` + Method string `json:"method"` + Path string `json:"path"` + Body string `json:"body,omitempty"` + Wait bool `json:"wait,omitempty"` + Status int `json:"status"` + Out any `json:"out"` + Job any `json:"job,omitempty"` + Actions []string `json:"actions"` + After map[string]string `json:"after"` + Tree []string `json:"tree"` +} + +// Les machines : nvidia-smi et python3 dans le PATH (bash et mkdir toujours). +func parityStrataMachines() map[string]map[string]string { + py := func(version string, venv bool) string { + s := "#!/bin/sh\ncase \"$1\" in\n--version) echo '" + version + "';;\n-c) " + if venv { + s += "exit 0;;\n" + } else { + s += "echo 'ModuleNotFoundError: No module named ensurepip'; exit 1;;\n" + } + return s + "esac\n" + } + ok := py("Python 3.12.3", true) + smi := func(rows string) string { + return "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '" + rows + "';;\nesac\n" + } + deux := smi(`0, NVIDIA GeForce RTX 3070, 8192, 100, 8.6, 00000000:01:00.0, 4, 4, 16, 16, 7001\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 5, 12.0, 00000000:02:00.0, 5, 5, 16, 16, 14001\n`) + return map[string]map[string]string{ + "sans-carte": {"python3": ok}, + "smi-en-panne": {"nvidia-smi": "#!/bin/sh\nexit 9\n", "python3": ok}, + "smi-vide": {"nvidia-smi": smi(``), "python3": ok}, + "vieille-carte": {"nvidia-smi": smi(`0, NVIDIA GeForce GTX 1080 Ti, 11264, 0, 6.1, 00000000:01:00.0, 3, 3, 16, 16, 5505\n`), "python3": ok}, + "petite-carte": {"nvidia-smi": smi(`0, NVIDIA GeForce RTX 3050, 6144, 0, 8.6, 00000000:01:00.0, 4, 4, 8, 8, 7001\n`), "python3": ok}, + "sans-python": {"nvidia-smi": deux}, + "python-casse": {"nvidia-smi": deux, "python3": "#!/bin/sh\nexit 1\n"}, + "python-muet": {"nvidia-smi": deux, "python3": py("Python inconnu", true)}, + "python-ancien": {"nvidia-smi": deux, "python3": py("Python 3.8.10", true)}, + "sans-venv": {"nvidia-smi": deux, "python3": py("Python 3.11.2", false)}, + "deux-cartes": {"nvidia-smi": deux, "python3": ok}, + "jumelles": {"nvidia-smi": smi(`0, NVIDIA GeForce RTX 4060 Ti, 16311, 0, 8.9, 00000000:01:00.0, 4, 4, 8, 8, 9001\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 0, 12.0, 00000000:02:00.0, 5, 5, 8, 8, 14001\n2, NVIDIA GeForce GTX 1650, 4096, 0, 7.46, 00000000:03:00.0, 3, 3, 16, 16, 4001\n`), + "python3": ok}, + "aide-ancienne": {"nvidia-smi": smi(`0, NVIDIA GeForce GTX 1070, 8192, 0, 6.1, 00000000:01:00.0, 3, 3, 16, 16, 4004\n1, NVIDIA GeForce RTX 4090, 24564, 0, 8.9, 00000000:02:00.0, 4, 4, 16, 16, 10501\n`), + "python3": ok}, + } +} + +// L'installeur factice : ses arguments, une barre de progression, puis ce +// que le modèle demandé lui fait faire. +const parityStrataSetup = `#!/bin/bash +echo "installeur : $*" +echo "cache : $XDG_CACHE_HOME" +printf 'modèle 10%%\r' +printf 'modèle 20%%\r' +echo "modèle téléchargé" +mkdir -p engine-cuda12 .venv/bin +fam=""; model=""; data="" +while [ $# -gt 0 ]; do + case "$1" in + --family) fam="$2"; shift;; + --model) model="$2"; shift;; + --data-dir) data="$2"; shift;; + esac + shift +done +case "$model" in +Q2_0) echo "erreur : téléchargement interrompu" >&2; exit 3;; +IQ2_XS) echo "rien d'écrit"; exit 0;; +esac +low=$(echo "$model" | tr 'A-Z' 'a-z') +if [ "$fam" = "swift" ]; then tag="swift-$low"; else tag="$low"; fi +mkdir -p "$data/packs/$tag" +printf '{"exe":"engine-cuda12/strata","args":["--pack","%s","--kv","int8","--spec","4","--max-context","131072","--vision","--vram-reserve-mib","700"],"vision":{"exe":"v","gpu":true},"gpu":0,"port":8080}\n' "$data/packs/$tag" > "strata-$tag.json" +echo "prêt : strata-$tag.json" +` + +func TestPariteStrata(t *testing.T) { + if runtime.GOARCH != "amd64" { + t.Skip("Strata n'est proposé que sous Linux x86_64") + } + home := testHome(t) + resetBackendsState() + t.Cleanup(resetBackendsState) + + tools := t.TempDir() + bash, err := exec.LookPath("bash") + if err != nil { + t.Skip("bash introuvable") + } + mkdir, _ := exec.LookPath("mkdir") + tr, _ := exec.LookPath("tr") + t.Setenv("PATH", tools) + machines := parityStrataMachines() + setMachine := func(name string) { + entries, _ := os.ReadDir(tools) + for _, e := range entries { + _ = os.Remove(filepath.Join(tools, e.Name())) + } + for n, p := range map[string]string{"bash": bash, "mkdir": mkdir, "tr": tr} { + if err := os.Symlink(p, filepath.Join(tools, n)); err != nil { + t.Fatal(err) + } + } + for n, body := range machines[name] { + if err := os.WriteFile(filepath.Join(tools, n), []byte(body), 0o755); err != nil { + t.Fatal(err) + } + } + } + + meminfo := filepath.Join(t.TempDir(), "meminfo") + oldMem, oldDisk, oldBase, oldSHA, oldSvc := meminfoPath, strataDiskFree, strataReleaseBase, strataAssetSHA, serviceActionOSFn + var mu sync.Mutex + var disk int64 + var actions []string + meminfoPath = meminfo + strataDiskFree = func(string) int64 { mu.Lock(); defer mu.Unlock(); return disk } + serviceActionOSFn = func(a string) error { mu.Lock(); defer mu.Unlock(); actions = append(actions, a); return nil } + t.Cleanup(func() { + meminfoPath, strataDiskFree, strataReleaseBase, strataAssetSHA, serviceActionOSFn = oldMem, oldDisk, oldBase, oldSHA, oldSvc + }) + + // La fausse release. + var rel parityStrataRel + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mu.Lock() + cur := rel + mu.Unlock() + if cur.Status != 0 { + w.WriteHeader(cur.Status) + return + } + switch strings.TrimPrefix(r.URL.Path, "/") { + case strataSrcAsset: + _, _ = w.Write(parityTarGz(t, cur.Src)) + case strataEngineAsset: + _, _ = w.Write([]byte(cur.Engine)) + default: + w.WriteHeader(404) + } + })) + defer srv.Close() + strataReleaseBase = srv.URL + "/" + setRelease := func(r parityStrataRel) { + mu.Lock() + rel = r + mu.Unlock() + sum := func(b []byte) string { h := sha256.Sum256(b); return hex.EncodeToString(h[:]) } + strataAssetSHA = map[string]string{ + strataSrcAsset: sum(parityTarGz(t, r.Src)), + strataEngineAsset: sum([]byte(r.Engine)), + } + if r.BadSHA { + strataAssetSHA[strataEngineAsset] = strings.Repeat("0", 64) + } + } + + mask := func(s string) string { + s = strings.ReplaceAll(s, srv.URL, "{{REL}}") + s = strings.ReplaceAll(s, home, "{{HOME}}") + return parityTSRe.ReplaceAllString(s, `"$1":"{{T}}"`) + } + unmask := func(s string) string { return strings.ReplaceAll(s, "{{HOME}}", home) } + handlers := map[string]http.HandlerFunc{ + "/api/strata": handleStrata, + "/api/strata/settings": handleStrataSettings, + "/api/strata/install": handleStrataInstall, + } + // L'arborescence : presets/ et strata/ (sans le contenu des archives, qui + // diffère d'une implémentation à l'autre). + tree := func() []string { + var out []string + for _, root := range []string{"presets", "strata"} { + _ = filepath.WalkDir(filepath.Join(home, root), func(p string, d fs.DirEntry, err error) error { + if err != nil { + return nil + } + rel, _ := filepath.Rel(home, p) + info, err := os.Lstat(p) + if err != nil { + return nil + } + switch { + case info.IsDir(): + out = append(out, "d "+rel) + case strings.HasPrefix(rel, "strata/dl/") || strings.HasPrefix(rel, "strata/prebuilt/"): + out = append(out, "f "+rel) + default: + b, _ := os.ReadFile(p) + out = append(out, "f "+rel+" "+info.Mode().Perm().String()+" "+mask(string(b))) + } + return nil + }) + } + sort.Strings(out) + return out + } + + src := []parityArchEntry{ + {Name: "ajean-moe-1.0/", Type: "dir", Mode: 0o755}, + {Name: "ajean-moe-1.0/setup.sh", Type: "file", Body: parityStrataSetup, Mode: 0o755}, + {Name: "ajean-moe-1.0/setup.py", Type: "file", Body: "# installeur\n", Mode: 0o644}, + {Name: "ajean-moe-1.0/serve/server.py", Type: "file", Body: "# serveur\n", Mode: 0o644}, + } + goodRel := parityStrataRel{Src: src, Engine: "moteur strata 1.0"} + mem47 := "MemTotal: 49283072 kB\nMemFree: 1000000 kB\nMemAvailable: 41943040 kB\n" + mem64 := "MemTotal: 67108864 kB\nMemAvailable: 65011712 kB\n" + mem16 := "MemTotal: 16777216 kB\nMemAvailable: 12582912 kB\n" + settings := func(preset string, ctx int, extra string) string { + return `{"preset":"` + preset + `","ctx":` + jsonInt(ctx) + `,"kv":"int8","spec":4,"vision":false,"helper":true` + extra + `}` + } + + var steps []parityStrataStep + run := func(st parityStrataStep) { + if st.Machine != "" { + setMachine(st.Machine) + } + if st.Meminfo != "" { + if err := os.WriteFile(meminfo, []byte(st.Meminfo), 0o644); err != nil { + t.Fatal(err) + } + } + if st.DiskFree != 0 { + mu.Lock() + disk = st.DiskFree + mu.Unlock() + } + files := map[string]string{} + for k, v := range st.Files { + files[k] = unmask(v) + } + parityApplyFiles(t, home, files) + for k, v := range st.Config { + if err := SetConfigKey(k, unmask(v)); err != nil { + t.Fatal(err) + } + } + for k, v := range st.State { + if err := putStr(bkState, k, v); err != nil { + t.Fatal(err) + } + } + if st.Release != nil { + setRelease(*st.Release) + } + mu.Lock() + actions = nil + mu.Unlock() + var lock *tuneLock + if st.Tune { + l, err := tuneLockAcquire("web", false) + if err != nil { + t.Fatal(err) + } + lock = l + } + rec := httptest.NewRecorder() + handlers[st.Path](rec, httptest.NewRequest(st.Method, st.Path, strings.NewReader(unmask(st.Body)))) + if lock != nil { + lock.release() + } + st.Status = rec.Code + if err := json.Unmarshal([]byte(mask(rec.Body.String())), &st.Out); err != nil { + t.Fatalf("%s : corps illisible %q", st.Name, rec.Body.String()) + } + if st.Wait { + deadline := time.Now().Add(30 * time.Second) + for lcJobSnapshot(0, false)["running"] == true { + if time.Now().After(deadline) { + t.Fatalf("%s : le job ne finit pas", st.Name) + } + time.Sleep(10 * time.Millisecond) + } + b, _ := json.Marshal(lcJobSnapshot(0, true)) + _ = json.Unmarshal([]byte(mask(string(b))), &st.Job) + } + mu.Lock() + st.Actions = append([]string{}, actions...) + mu.Unlock() + st.After = map[string]string{} + cfg := ReadConfig() + for _, k := range []string{"ENGINE", "STRATA_CONFIG", "CTX", "STRATA_KV", "STRATA_HELPER"} { + if v := cfg[k]; v != "" { + st.After["config/"+k] = mask(v) + } + } + st.Tree = tree() + steps = append(steps, st) + } + + for _, st := range []parityStrataStep{ + {Name: "aucune carte", Machine: "sans-carte", Meminfo: mem47, DiskFree: 400e9, Method: "GET", Path: "/api/strata"}, + {Name: "nvidia-smi en panne", Machine: "smi-en-panne", Method: "GET", Path: "/api/strata"}, + {Name: "nvidia-smi sans carte", Machine: "smi-vide", Method: "GET", Path: "/api/strata"}, + {Name: "carte trop ancienne", Machine: "vieille-carte", Method: "GET", Path: "/api/strata"}, + {Name: "carte trop petite", Machine: "petite-carte", Method: "GET", Path: "/api/strata"}, + {Name: "sans Python", Machine: "sans-python", Method: "GET", Path: "/api/strata"}, + {Name: "Python en panne", Machine: "python-casse", Method: "GET", Path: "/api/strata"}, + {Name: "Python illisible", Machine: "python-muet", Method: "GET", Path: "/api/strata"}, + {Name: "Python trop ancien", Machine: "python-ancien", Method: "GET", Path: "/api/strata"}, + {Name: "sans venv", Machine: "sans-venv", Method: "GET", Path: "/api/strata"}, + {Name: "deux cartes, 47 Go", Machine: "deux-cartes", Method: "GET", Path: "/api/strata"}, + {Name: "trois cartes, la plus récente devant", Machine: "jumelles", Method: "GET", Path: "/api/strata"}, + {Name: "carte d'aide trop ancienne", Machine: "aide-ancienne", Method: "GET", Path: "/api/strata"}, + {Name: "64 Go de RAM", Machine: "deux-cartes", Meminfo: mem64, Method: "GET", Path: "/api/strata"}, + {Name: "16 Go de RAM", Meminfo: mem16, Method: "GET", Path: "/api/strata"}, + {Name: "disque presque plein", Meminfo: mem47, DiskFree: 50e9, Method: "GET", Path: "/api/strata"}, + {Name: "disque juste trop petit", DiskFree: 78e9, Method: "GET", Path: "/api/strata"}, + {Name: "données déjà là", DiskFree: 60e9, Files: map[string]string{ + "strata/data/models/swift-IQ3_XXS/a.gguf": strings.Repeat("x", 2000), + }, Method: "GET", Path: "/api/strata"}, + {Name: "meminfo sans MemAvailable", DiskFree: 400e9, Meminfo: "MemTotal: 49283072 kB\n", Method: "GET", Path: "/api/strata"}, + + // Réglages. + {Name: "réglages en GET", Meminfo: mem47, Method: "GET", Path: "/api/strata/settings"}, + {Name: "réglages illisibles", Method: "POST", Path: "/api/strata/settings", Body: `{"ctx":"x"}`}, + {Name: "réglages sans preset", Method: "POST", Path: "/api/strata/settings", Body: settings("", 65536, "")}, + {Name: "réglages, preset avec chemin", Method: "POST", Path: "/api/strata/settings", Body: settings("../x", 65536, "")}, + {Name: "réglages, preset absent", Method: "POST", Path: "/api/strata/settings", Body: settings("absent", 65536, "")}, + {Name: "réglages, preset llama.cpp", Files: map[string]string{"presets/llama.env": "MODEL=/m.gguf\n"}, + Method: "POST", Path: "/api/strata/settings", Body: settings("llama", 65536, "")}, + {Name: "réglages hors limites", Files: map[string]string{"presets/S.env": "# NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nCTX=131072\n"}, + Method: "POST", Path: "/api/strata/settings", Body: settings("S", 1000, "")}, + {Name: "réglages, experts inconnus", Method: "POST", Path: "/api/strata/settings", Body: settings("S", 65536, `,"experts":"nvme"`)}, + {Name: "réglages d'un preset inactif", Method: "POST", Path: "/api/strata/settings", Body: settings("S", 65536, `,"experts":"disk"`)}, + {Name: "réglages du preset actif", Config: map[string]string{"ENGINE": "strata", "STRATA_HELPER_GPU": "0", "CTX": "65536", + "STRATA_KV": "int8", "STRATA_SPEC": "4", "STRATA_VISION": "0", "STRATA_HELPER": "1", "STRATA_EXPERTS": "disk"}, + Method: "POST", Path: "/api/strata/settings", Body: settings("S", 98304, "")}, + {Name: "réglages du preset actif pendant une optimisation", Tune: true, + Method: "POST", Path: "/api/strata/settings", Body: settings("S", 98304, "")}, + + // Installation. + {Name: "installation en GET", Method: "GET", Path: "/api/strata/install"}, + {Name: "installation illisible", Method: "POST", Path: "/api/strata/install", Body: `[`}, + {Name: "installation d'un quant inconnu", Method: "POST", Path: "/api/strata/install", Body: `{"family":"swift","quant":"Q2_0"}`}, + {Name: "installation pendant une optimisation", Tune: true, Method: "POST", Path: "/api/strata/install", Body: `{"family":"swift","quant":"IQ3_XXS"}`}, + {Name: "installation sur une machine sans carte", Machine: "sans-carte", Method: "POST", Path: "/api/strata/install", + Body: `{"family":"swift","quant":"IQ3_XXS"}`, Wait: true}, + {Name: "installation qui ne tient pas", Machine: "deux-cartes", Meminfo: mem16, Method: "POST", Path: "/api/strata/install", + Body: `{"family":"qwen","quant":"IQ3_S"}`, Wait: true}, + {Name: "release introuvable", Meminfo: mem47, Release: &parityStrataRel{Status: 404, Src: src, Engine: "x"}, + Method: "POST", Path: "/api/strata/install", Body: `{"family":"swift","quant":"IQ3_XXS"}`, Wait: true}, + {Name: "moteur altéré", Release: &parityStrataRel{Src: src, Engine: "moteur strata 1.0", BadSHA: true}, + Method: "POST", Path: "/api/strata/install", Body: `{"family":"swift","quant":"IQ3_XXS"}`, Wait: true}, + {Name: "installation", Release: &goodRel, Method: "POST", Path: "/api/strata/install", + Body: `{"family":"swift","quant":"IQ3_XXS"}`, Wait: true}, + {Name: "après l'installation", Method: "GET", Path: "/api/strata"}, + {Name: "mode lancé connu, modèles inactifs", State: map[string]string{"strata_experts_mode": "drop"}, Files: map[string]string{ + "presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env": "# NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\n" + + "STRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env": "ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\n" + + "STRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + }, Method: "GET", Path: "/api/strata"}, + {Name: "experts.bin et moteur du paquet", Files: map[string]string{ + "strata/data/packs/swift-iq3_xxs/experts.bin": "x", + }, State: map[string]string{"strata_experts_mode": ""}, Method: "GET", Path: "/api/strata"}, + {Name: "RAM juste sous le seuil du mode hors RAM", Meminfo: "MemTotal: 49283072 kB\nMemAvailable: 43164063 kB\n", + Method: "GET", Path: "/api/strata"}, + {Name: "RAM au-dessus du seuil du mode hors RAM", Meminfo: "MemTotal: 49283072 kB\nMemAvailable: 43457032 kB\n", + Method: "GET", Path: "/api/strata"}, + {Name: "mode hors RAM coupé dans le preset", Files: map[string]string{ + "presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env": "# NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\n" + + "STRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\n" + + "STRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=0\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + }, Method: "GET", Path: "/api/strata"}, + {Name: "moteur d'un autre paquet", Meminfo: mem47, Files: map[string]string{ + "strata/ajean-moe-1.0/engine-cuda12/.loki-engine": "ajean-moe-engine-0.9-linux-x64-cuda12.zip\n", + }, Method: "GET", Path: "/api/strata"}, + {Name: "réinstallation, moteur téléchargé périmé", Files: map[string]string{ + "strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip": "ancien moteur", + }, Method: "POST", Path: "/api/strata/install", Body: `{"family":"swift","quant":"IQ3_XXS"}`, Wait: true}, + {Name: "installeur en échec", Method: "POST", Path: "/api/strata/install", Body: `{"family":"qwen","quant":"Q2_0"}`, Wait: true}, + {Name: "installeur sans configuration", Method: "POST", Path: "/api/strata/install", Body: `{"family":"qwen","quant":"IQ2_XS"}`, Wait: true}, + {Name: "configuration de lancement disparue", Files: map[string]string{ + "strata/ajean-moe-1.0/strata-swift-iq3_xxs.json": "-", + }, Method: "GET", Path: "/api/strata"}, + {Name: "configuration de lancement illisible", Files: map[string]string{ + "strata/ajean-moe-1.0/strata-swift-iq3_xxs.json": "[1]", + }, Method: "GET", Path: "/api/strata"}, + } { + run(st) + } + + got, err := parityJSON(map[string]any{"machines": machines, "setup": parityStrataSetup, "steps": steps}) + if err != nil { + t.Fatal(err) + } + if os.Getenv("LOKI_PARITY_UPDATE") == "1" { + if err := os.MkdirAll(filepath.Dir(parityStrataFile), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(parityStrataFile, got, 0o644); err != nil { + t.Fatal(err) + } + return + } + want, err := os.ReadFile(parityStrataFile) + if err != nil { + t.Fatalf("journal de référence absent (%v) : LOKI_PARITY_UPDATE=1 pour le créer", err) + } + if string(got) != string(want) { + t.Errorf("Strata ne produit plus le journal rangé dans %s.\n"+ + "Si c'est voulu : LOKI_PARITY_UPDATE=1 go test ./internal/loki -run TestPariteStrata,\n"+ + "puis cargo test --test strata dit si le port Rust suit.\n--- obtenu ---\n%s", parityStrataFile, got) + } +} + +func jsonInt(n int) string { + b, _ := json.Marshal(n) + return string(b) +} diff --git a/internal/loki/sys_platform_unix.go b/internal/loki/sys_platform_unix.go index 5ffecee..68f9b9a 100644 --- a/internal/loki/sys_platform_unix.go +++ b/internal/loki/sys_platform_unix.go @@ -85,7 +85,7 @@ func totalRAMGB() float64 { } return 0 } - b, err := os.ReadFile("/proc/meminfo") + b, err := os.ReadFile(meminfoPath) if err != nil { return 0 } diff --git a/internal/loki/sys_service.go b/internal/loki/sys_service.go index b1a093f..5a8da04 100644 --- a/internal/loki/sys_service.go +++ b/internal/loki/sys_service.go @@ -31,9 +31,13 @@ func serviceAction(action string) error { } tuneReapStale() } - return serviceActionOS(action) + return serviceActionOSFn(action) } +// serviceActionOSFn : serviceActionOS, remplaçable par les tests (une bascule +// de preset ne doit pas lancer de vrai service depuis `go test`). +var serviceActionOSFn = serviceActionOS + // preflightEngine vérifie ce sans quoi le moteur ne PEUT pas démarrer, avant de // lancer le service. Sinon llama-server sortait en erreur, systemd le relançait // toutes les 3 s, et `loki start` affichait un « activating » rassurant pendant diff --git a/rust/loki-rs/src/api.rs b/rust/loki-rs/src/api.rs index 4551dbd..248cf77 100644 --- a/rust/loki-rs/src/api.rs +++ b/rust/loki-rs/src/api.rs @@ -59,6 +59,9 @@ pub struct Ctx { /// Panneau « moteur de l'image » tenu par la façade /// (`LOKI_ENGINE_IMAGE=rust`, avec les backends). pub engineimg: Option>, + /// Strata (écran, réglages, installation) tenu par la façade + /// (`LOKI_STRATA=rust`, avec les backends). + pub strata: Option>, /// Jeton de l'API interne : une requête qui le porte vient du Go. pub internal_token: String, } @@ -82,6 +85,7 @@ impl Ctx { || self.update || self.backends.is_some() || self.engineimg.is_some() + || self.strata.is_some() } /// La requête vient du Go (jeton interne valide) : déjà authentifiée par diff --git a/rust/loki-rs/src/lib.rs b/rust/loki-rs/src/lib.rs index 337feed..0c25aad 100644 --- a/rust/loki-rs/src/lib.rs +++ b/rust/loki-rs/src/lib.rs @@ -40,6 +40,7 @@ pub mod push; pub mod serve; pub mod settings; pub mod store; +pub mod strata; pub mod sysinfo; pub mod system; pub mod sysupdate; diff --git a/rust/loki-rs/src/main.rs b/rust/loki-rs/src/main.rs index 878cc2a..b9cfb0e 100644 --- a/rust/loki-rs/src/main.rs +++ b/rust/loki-rs/src/main.rs @@ -174,6 +174,12 @@ fn serve() -> ExitCode { if held_by_facade("LOKI_ENGINE_IMAGE") && !backends_rust { eprintln!("[loki-rs] moteur de l'image tenu par le Go (LOKI_BACKENDS=rust requis)"); } + // LOKI_STRATA=rust : l'écran de Strata, ses réglages et son + // installation (un job des moteurs : avec les backends seulement). + let strata_rust = held_by_facade("LOKI_STRATA") && backends_rust; + if held_by_facade("LOKI_STRATA") && !backends_rust { + eprintln!("[loki-rs] Strata tenu par le Go (LOKI_BACKENDS=rust requis)"); + } let engine_rust = held_by_facade("LOKI_ENGINE") && match loki_rs::enginectl::usable( std::env::var("LOKI_CONTAINER").ok().as_deref(), @@ -207,6 +213,7 @@ fn serve() -> ExitCode { ("LOKI_UPDATE", update_rust), ("LOKI_BACKENDS", backends_rust), ("LOKI_ENGINE_IMAGE", engineimg_rust), + ("LOKI_STRATA", strata_rust), ]; for (var, on) in held { if on { @@ -332,6 +339,12 @@ fn serve() -> ExitCode { ], )) }); + let strata = strata_rust.then(|| { + std::sync::Arc::new(loki_rs::strata::api::Strata::new( + engine_paths.home.clone(), + loki_rs::backends::probe::Probe::system(), + )) + }); let cfg = proxy::Config { backend, internal_token: token, @@ -352,6 +365,7 @@ fn serve() -> ExitCode { update: update_rust, backends, engineimg, + strata, mcp: mcp_rust.then(|| std::sync::Arc::new(loki_rs::mcp::Mcp::new(mem_home))), }; let res = proxy::serve(listener, cfg, shutdown_signal()).await; diff --git a/rust/loki-rs/src/presets_api.rs b/rust/loki-rs/src/presets_api.rs index 8fd4565..9b1eca5 100644 --- a/rust/loki-rs/src/presets_api.rs +++ b/rust/loki-rs/src/presets_api.rs @@ -832,7 +832,7 @@ async fn tune_deny(store: &Store) -> Option> { /// Applique un preset à la configuration vivante (au Go, voir /// `facade_presets.go`). -async fn preset_apply(store: &Store, path: &Path, mode: &str) -> Result<(), String> { +pub(crate) async fn preset_apply(store: &Store, path: &Path, mode: &str) -> Result<(), String> { let (code, v) = store .internal_post( "/internal/v1/preset/apply", diff --git a/rust/loki-rs/src/proxy.rs b/rust/loki-rs/src/proxy.rs index 4b7e64f..04fc2b9 100644 --- a/rust/loki-rs/src/proxy.rs +++ b/rust/loki-rs/src/proxy.rs @@ -100,6 +100,9 @@ pub struct Config { /// registre, bascules, rendu du gabarit) tenu par la façade /// (`LOKI_ENGINE_IMAGE=rust`) ; `None` : au Go. pub engineimg: Option>, + /// Strata (machine, réglages, installation) tenu par la façade + /// (`LOKI_STRATA=rust`) ; `None` : au Go. + pub strata: Option>, } struct Proxy { @@ -141,6 +144,7 @@ pub async fn serve( update: cfg.update, backends: cfg.backends, engineimg: cfg.engineimg, + strata: cfg.strata, internal_token: cfg.internal_token.clone(), }, }); @@ -250,6 +254,11 @@ impl Proxy { { return crate::engineimg::serve(&self.ctx, e, req, from_go).await; } + if let Some(s) = &self.ctx.strata + && crate::strata::api::handles(path) + { + return crate::strata::api::serve(&self.ctx, s, req, from_go).await; + } if let Some(b) = &self.ctx.backends && crate::backends::handles(path) { diff --git a/rust/loki-rs/src/strata/api.rs b/rust/loki-rs/src/strata/api.rs new file mode 100644 index 0000000..035764c --- /dev/null +++ b/rust/loki-rs/src/strata/api.rs @@ -0,0 +1,926 @@ +//! Routes de Strata tenues par la façade (lot 25) : la machine et ce qui y +//! tient (`/api/strata`), les réglages d'un modèle installé +//! (`/api/strata/settings`) et l'installation (`/api/strata/install`, un job +//! des moteurs : paquet figé vérifié, installeur de Strata, preset, bascule). + +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; + +use http_body_util::{BodyExt, Limited}; +use hyper::body::Incoming; +use hyper::{Method, Request, Response, StatusCode}; +use serde_json::{Value, json}; +use sha2::Digest; + +use super::*; +use crate::api::Ctx; +use crate::auth::json as send_json; +use crate::backends::probe::Probe; +use crate::backends::{Backends, Log}; +use crate::gojson::{self, Kind}; +use crate::proxy::Body; +use crate::store::{BK_STATE, Store}; + +const SETTINGS_REQ: &str = "strataSettingsReq"; +const INSTALL_REQ: &str = "strataInstallReq"; + +/// Strata, tenu par la façade. +pub struct Strata { + pub paths: Paths, + /// PATH des outils (nvidia-smi, python3, bash) et racine de /proc. + pub probe: Probe, + /// `strataReleaseBase`. + pub release_base: String, + /// `strataAssetSHA`. + pub asset_sha: Mutex>, + /// Linux x86_64 (le seul paquet publié). + pub platform_ok: bool, + /// Place libre imposée (tests) ; `None` : celle du disque. + pub disk_free: Mutex>, + client: reqwest::Client, +} + +impl Strata { + pub fn new(home: PathBuf, probe: Probe) -> Self { + crate::chat::engine::install_crypto(); + Strata { + paths: Paths { home }, + probe, + release_base: RELEASE_BASE.into(), + asset_sha: Mutex::new(default_asset_sha()), + platform_ok: cfg!(all(target_os = "linux", target_arch = "x86_64")), + disk_free: Mutex::new(None), + client: reqwest::Client::builder().build().unwrap_or_default(), + } + } + + fn meminfo(&self) -> Option { + std::fs::read_to_string(self.probe.sys("/proc/meminfo")).ok() + } + + /// `totalRAMGB` (Linux) : MemTotal, en Gio. + pub fn total_ram_gb(&self) -> f64 { + let Some(b) = self.meminfo() else { + return 0.0; + }; + for line in b.split('\n') { + if line.starts_with("MemTotal:") { + let f: Vec<&str> = line.split_whitespace().collect(); + if f.len() >= 2 + && let Ok(kb) = f[1].parse::() + { + return kb / (1024.0 * 1024.0); + } + } + } + 0.0 + } + + /// `memAvailableGB` : MemAvailable, en Go ; la RAM totale à défaut. + pub fn mem_available_gb(&self) -> f64 { + let Some(b) = self.meminfo() else { + return self.total_ram_gb(); + }; + for line in b.split('\n') { + if let Some(v) = line.strip_prefix("MemAvailable:") + && let Some(f) = v.split_whitespace().next() + && let Ok(kb) = f.parse::() + { + return kb * 1024.0 / 1e9; + } + } + self.total_ram_gb() + } + + /// `strataEngineRSSGB` : la RAM tenue par le moteur Strata en marche + /// (arbre du service), en Go. + pub fn engine_rss_gb(&self, cfg: &Cfg) -> f64 { + if !is_strata(cfg) { + return 0.0; + } + let svc = std::env::var("LOKI_SERVICE") + .ok() + .filter(|s| !s.is_empty()) + .unwrap_or_else(|| "loki-engine".into()); + let root: i64 = std::fs::read_to_string(self.paths.home.join(format!("{svc}.pid"))) + .ok() + .and_then(|s| s.trim().parse().ok()) + .unwrap_or(0); + if root <= 0 { + return 0.0; + } + let proc_dir = self.probe.sys("/proc"); + let Ok(rd) = std::fs::read_dir(&proc_dir) else { + return 0.0; + }; + let mut parent: HashMap = HashMap::new(); + let mut rss: HashMap = HashMap::new(); + for e in rd.flatten() { + let Ok(pid) = e.file_name().to_string_lossy().parse::() else { + continue; + }; + let Ok(b) = std::fs::read_to_string(e.path().join("status")) else { + continue; + }; + for line in b.split('\n') { + if let Some(v) = line.strip_prefix("PPid:") { + parent.insert(pid, v.trim().parse().unwrap_or(0)); + } else if let Some(v) = line.strip_prefix("VmRSS:") + && let Some(f) = v.split_whitespace().next() + { + rss.insert(pid, f.parse::().unwrap_or(0.0) * 1024.0 / 1e9); + } + } + } + let mut total = 0.0; + for (pid, r) in &rss { + let (mut p, mut n) = (*pid, 0); + while p > 0 && n < 64 { + if p == root { + total += r; + break; + } + p = parent.get(&p).copied().unwrap_or(0); + n += 1; + } + } + total + } + + /// `strataCheckPython` : Python 3.10+ et son module venv. + pub async fn check_python(&self) -> Result { + let Some(py) = self.probe.look_path("python3") else { + return Err(( + String::new(), + "Python 3 est introuvable : installe-le (apt install python3 python3-venv)".into(), + )); + }; + let py_s = py.to_string_lossy().into_owned(); + let mut c = tokio::process::Command::new(&py); + c.arg("--version").stdin(std::process::Stdio::null()); + let (out, err) = crate::backends::devices::combined(c, &py_s, None).await; + if err.is_some() { + return Err(( + String::new(), + "Python 3 est introuvable : installe-le (apt install python3 python3-venv)".into(), + )); + } + let re = regex::Regex::new(r"Python ([0-9]+)\.([0-9]+)").expect("motif"); + let Some(m) = re.captures(&out) else { + return Err(( + String::new(), + format!("version de Python illisible : {}", out.trim()), + )); + }; + let maj: i64 = m[1].parse().unwrap_or(0); + let mnr: i64 = m[2].parse().unwrap_or(0); + let ver = format!("{}.{}", &m[1], &m[2]); + if maj < 3 || (maj == 3 && mnr < 10) { + return Err(( + ver.clone(), + format!("Python {ver} est trop ancien : il faut Python 3.10 ou plus récent"), + )); + } + let mut c = tokio::process::Command::new(&py); + c.args(["-c", "import venv, ensurepip"]) + .stdin(std::process::Stdio::null()); + let (_, err) = crate::backends::devices::combined(c, &py_s, None).await; + if err.is_some() { + return Err(( + ver.clone(), + format!("le module venv de Python manque : apt install python{ver}-venv"), + )); + } + Ok(ver) + } + + /// `strataDetect` : la machine, pour l'écran d'installation. + pub async fn detect(&self, cfg: &Cfg) -> Env { + let mut env = Env { + ram_gb: self.total_ram_gb(), + ..Env::default() + }; + env.avail_gb = (self.mem_available_gb() + self.engine_rss_gb(cfg)).min(env.ram_gb); + let forced = *self.disk_free.lock().unwrap_or_else(|e| e.into_inner()); + let free = forced.unwrap_or_else(|| { + crate::downloads::disk_free(&self.paths.strata_home().to_string_lossy()) + }); + if free > 0 { + env.disk_free_gb = free as f64 / 1e9; + } + if !self.platform_ok { + env.reason = "Strata n'est proposé que sous Linux (x86_64)".into(); + return env; + } + let gpus = match self.probe.detect_gpus().await { + Ok(g) if !g.is_empty() => g, + Ok(_) => { + env.reason = "Strata demande une carte NVIDIA (aucune carte détectée)".into(); + return env; + } + Err(e) => { + env.reason = format!("Strata demande une carte NVIDIA ({e})"); + return env; + } + }; + for g in gpus { + let mib: f64 = g.mem_total.trim().parse().unwrap_or(0.0); + let cc: f64 = g.cap.trim().parse().unwrap_or(0.0); + env.gpus.push(Gpu { + index: g.index, + name: g.name, + vram_gb: mib / 1024.0, + arch: (cc * 10.0 + 0.5) as i64, + }); + } + let mut cards = env.gpus.clone(); + cards.sort_by(|a, b| { + if a.vram_gb != b.vram_gb { + b.vram_gb + .partial_cmp(&a.vram_gb) + .unwrap_or(std::cmp::Ordering::Equal) + } else { + b.arch.cmp(&a.arch) + } + }); + if cards[0].arch < MIN_ARCH { + env.reason = format!( + "la carte {} est trop ancienne pour Strata (RTX 20 ou plus récente)", + cards[0].name + ); + return env; + } + if cards[0].vram_gb < 7.5 { + env.reason = format!( + "la carte {} n'a que {} Go de VRAM (8 Go minimum)", + cards[0].name, + f0(cards[0].vram_gb) + ); + return env; + } + env.main = cards[0].index; + if cards.len() > 1 && cards[1].arch >= MIN_ARCH && cards[1].vram_gb >= 5.5 { + env.helper = cards[1].index; + } + match self.check_python().await { + Ok(v) => { + env.python = v; + env.supported = true; + } + Err((v, e)) => { + env.python = v; + env.reason = e; + } + } + env + } + + /// `strataDetailsFor` : la config de lancement d'un preset installé, en + /// clair (celle que le lancement calculerait). + pub async fn details_for( + &self, + store: &Store, + cfg: &Cfg, + order: &[String], + id: &str, + env: &Env, + ) -> Option { + let content = crate::presets_api::read_preset(&self.paths.home, id).ok()?; + let pc = crate::presets::parse_env(&content); + let raw = std::fs::read(cfg_get(&pc, "STRATA_CONFIG")).ok()?; + let base: Value = serde_json::from_slice(&raw).ok()?; + if !base.is_object() { + return None; + } + let mut mode = resolve_experts( + &self.paths, + &pc, + &arg_list(&base), + env.avail_gb, + helper_vram(&pc, &env.gpus), + ) + .to_string(); + let active = crate::presets::list_presets(&self.paths.home, cfg, order) + .ok() + .and_then(|l| l.into_iter().find(|p| p.id == id)) + .is_some_and(|p| p.active); + if active { + let m = store.get_str(BK_STATE, LAUNCH_MODE_KEY).await; + if !m.is_empty() { + mode = m; + } + } + let out = build_config(&base, &pc, "", &mode).ok()?; + let args = arg_list(&out); + let val = |flag: &str| -> String { + args.windows(2) + .find(|w| w[0] == flag) + .map(|w| w[1].clone()) + .unwrap_or_default() + }; + let gpu_name = |idx: &str| -> String { + env.gpus + .iter() + .find(|g| g.index.to_string() == idx.trim()) + .map(|g| { + format!( + "{} ({} Go)", + g.name.strip_prefix("NVIDIA GeForce ").unwrap_or(&g.name), + f0(g.vram_gb) + ) + }) + .unwrap_or_default() + }; + let main_gpu = gpu_name(cfg_get(&pc, "STRATA_MAIN_GPU")); + let mut experts = cfg_get(&pc, "STRATA_EXPERTS").trim().to_lowercase(); + if experts != EXPERTS_RAM && experts != EXPERTS_DISK { + experts = EXPERTS_AUTO.into(); + } + let mut d = json!({ + "version": VERSION, "ctx": val("--max-context"), "kv": val("--kv"), + "spec": val("--spec"), "prefill": val("--prefill"), "short_read": val("--short-read"), + "cache_root": val("--prompt-cache-root"), + "mmap": mode == "disk" || mode == "arena", "drop": mode == "drop", + "experts": experts, "mode_label": experts_label(&mode), "mode": mode, + "main_gpu": main_gpu, + "has_helper": false, "helper_on": false, + }); + let kvr = val("--kv-resident"); + if !kvr.is_empty() { + d["kv_resident"] = json!(kvr); + } + let h = cfg_get(&pc, "STRATA_HELPER_GPU").trim(); + if !h.is_empty() && h != "-1" { + d["has_helper"] = json!(true); + if helper_on(&pc) { + d["helper_on"] = json!(true); + let hg = gpu_name(h); + if !hg.is_empty() { + d["helper_gpu"] = json!(hg); + } + } + } + let vision = cfg_get(&pc, "STRATA_VISION") != "0"; + d["vision"] = json!(vision); + if vision && let Some(Value::Object(v)) = out.get("vision") { + let vg = match v.get("cuda_device") { + Some(dev) => gpu_name(&go_sprint(dev)), + None => main_gpu.clone(), + }; + if !vg.is_empty() { + d["vision_gpu"] = json!(vg); + } + } + Some(d) + } + + /// `handleStrata`. + pub async fn overview(&self, store: &Store) -> Value { + let cfg = store.config().await; + let order = crate::presets::parse_preset_order( + store + .get(BK_STATE, crate::presets::PRESET_ORDER_KEY) + .await + .ok() + .flatten() + .as_deref(), + ); + let env = self.detect(&cfg).await; + let mut installed: Vec = Vec::new(); + let mut active: HashMap = HashMap::new(); + if let Ok(list) = crate::presets::list_presets(&self.paths.home, &cfg, &order) { + for p in list { + if let Ok(c) = crate::presets_api::read_preset(&self.paths.home, &p.id) + && is_strata(&crate::presets::parse_env(&c)) + { + installed.push(p.id.clone()); + active.insert(p.id, p.active); + } + } + } + let mut fams = Vec::new(); + for f in FAMILIES { + let mut fits = Vec::new(); + for id in f.quants { + let q = quant(id).expect("quant"); + let mut fit = fit_for(q, &env, have_gb(&self.paths, f.id, id)); + let pid = preset_name(f.id, id); + if let Some(a) = active.get(&pid) { + fit.preset = pid.clone(); + fit.active = *a; + fit.details = self.details_for(store, &cfg, &order, &pid, &env).await; + } + fits.push(fit.to_json()); + } + fams.push(json!({ + "id": f.id, "label": f.label, "about": f.about, "quants": f.quants, + "fits": fits, "recommend": recommend(&self.paths, f.id, &env), + })); + } + json!({ + "version": VERSION, "env": env.to_json(), "families": fams, + "installed": installed, "active": is_strata(&cfg), + }) + } + + // --- installation ---------------------------------------------------- + + fn sha256_file(p: &Path) -> Result { + let mut f = std::fs::File::open(p) + .map_err(|e| crate::paths::os_err("open", &p.to_string_lossy(), &e))?; + let mut h = sha2::Sha256::new(); + let mut buf = vec![0u8; 1 << 16]; + loop { + let n = std::io::Read::read(&mut f, &mut buf).map_err(|e| e.to_string())?; + if n == 0 { + break; + } + h.update(&buf[..n]); + } + Ok(hex::encode(h.finalize())) + } + + /// `strataFetch` : un fichier de la release figée, vérifié par SHA-256. + async fn fetch(&self, log: &Log<'_>, asset: &str) -> Result { + let want = self + .asset_sha + .lock() + .unwrap_or_else(|e| e.into_inner()) + .get(asset) + .cloned() + .unwrap_or_default(); + let dl = self.paths.dl_dir(); + let dst = dl.join(asset); + if Self::sha256_file(&dst).is_ok_and(|g| g == want) { + log.line(&format!("{asset} déjà téléchargé")).await; + return Ok(dst); + } + std::fs::create_dir_all(&dl) + .map_err(|e| crate::paths::os_err("mkdir", &dl.to_string_lossy(), &e))?; + log.phase(&format!("téléchargement de {asset}…")).await; + let tmp = PathBuf::from(format!("{}.part", dst.to_string_lossy())); + let rq = self.client.get(format!("{}{asset}", self.release_base)); + if let Err(e) = crate::backends::log_download(log, rq, &tmp, 0).await { + let _ = std::fs::remove_file(&tmp); + return Err(format!("téléchargement de {asset} : {e}")); + } + let got = Self::sha256_file(&tmp)?; + if got != want { + let _ = std::fs::remove_file(&tmp); + return Err(format!( + "{asset} : empreinte SHA-256 inattendue (fichier altéré ou incomplet)" + )); + } + std::fs::rename(&tmp, &dst).map_err(|e| { + // *os.LinkError : « rename ancien nouveau: erreur ». + crate::paths::os_err( + "rename", + &format!("{} {}", tmp.to_string_lossy(), dst.to_string_lossy()), + &e, + ) + })?; + Ok(dst) + } + + /// `runStepEnv` avec le job pour journal : la sortie mêlée, découpée en + /// lignes comme le `sinkWriter` du Go. + async fn run_logged( + &self, + log: &Log<'_>, + dir: &Path, + name: &str, + args: &[String], + env: &[(&str, String)], + ) -> Result<(), String> { + let Some(bin) = self.probe.look_path(name) else { + return Err(format!( + "exec: \"{name}\": executable file not found in $PATH" + )); + }; + let (reader, writer) = std::io::pipe().map_err(|e| e.to_string())?; + let writer2 = writer.try_clone().map_err(|e| e.to_string())?; + let mut c = tokio::process::Command::new(&bin); + c.args(args) + .current_dir(dir) + .stdin(std::process::Stdio::null()) + .stdout(std::process::Stdio::from(writer)) + .stderr(std::process::Stdio::from(writer2)); + for (k, v) in env { + c.env(k, v); + } + let mut child = c + .spawn() + .map_err(|e| crate::paths::os_err("fork/exec", &bin.to_string_lossy(), &e))?; + drop(c); + let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::>(); + let read = tokio::task::spawn_blocking(move || { + let mut r = reader; + let mut buf = [0u8; 8192]; + loop { + match std::io::Read::read(&mut r, &mut buf) { + Ok(0) | Err(_) => break, + Ok(n) => { + if tx.send(buf[..n].to_vec()).is_err() { + break; + } + } + } + } + }); + let mut sink = SinkWriter::default(); + while let Some(chunk) = rx.recv().await { + for l in sink.write(&chunk) { + log.line(&l).await; + } + } + let _ = read.await; + let status = child.wait().await.map_err(|e| e.to_string())?; + match status.code() { + Some(0) => Ok(()), + Some(code) => Err(format!("exit status {code}")), + None => Err(status.to_string()), + } + } + + /// `strataRunInstall` : le corps du job d'installation. + async fn run_install(&self, ctx: &Ctx, b: &Backends, family: &str, quant_id: &str) { + let store = &ctx.store; + let log = Log { + jobs: &b.jobs, + store, + }; + let cfg = store.config().await; + let env = self.detect(&cfg).await; + if !env.supported { + return b.jobs.fail(store, &env.reason).await; + } + let Some(q) = quant(quant_id) else { + return b + .jobs + .fail(store, &format!("quant inconnu : {quant_id}")) + .await; + }; + let fit = fit_for(q, &env, have_gb(&self.paths, family, q.id)); + if !fit.ok { + return b + .jobs + .fail( + store, + &format!("{} ne tient pas sur cette machine : {}", q.id, fit.why), + ) + .await; + } + let src = match self.fetch(&log, SRC_ASSET).await { + Ok(p) => p, + Err(e) => return b.jobs.fail(store, &e).await, + }; + let engine = match self.fetch(&log, ENGINE_ASSET).await { + Ok(p) => p, + Err(e) => return b.jobs.fail(store, &e).await, + }; + let src_dir = self.paths.src_dir(); + let home = self.paths.strata_home(); + if std::fs::metadata(src_dir.join("setup.py")).is_err() { + log.phase("décompression de Strata…").await; + let (s2, h2) = (src.clone(), home.clone()); + let r = + tokio::task::spawn_blocking(move || crate::backends::prebuilt::extract(&s2, &h2)) + .await + .unwrap_or_else(|e| Err(e.to_string())); + if let Err(e) = r { + return b.jobs.fail(store, &format!("décompression : {e}")).await; + } + } + let pre = home.join("prebuilt"); + let _ = std::fs::create_dir_all(&pre); + let dst = pre.join(ENGINE_LOCAL); + if let Err(e) = std::fs::copy(&engine, &dst) { + return b + .jobs + .fail( + store, + &crate::paths::os_err("open", &dst.to_string_lossy(), &e), + ) + .await; + } + log.phase(&format!( + "installation de {} {} (téléchargement de ~{} Go)…", + family_label(family), + q.id, + f0(q.download_gb) + )) + .await; + let mut pre_s = pre.to_string_lossy().into_owned(); + pre_s.push(std::path::MAIN_SEPARATOR); + let args: Vec = [ + "setup.sh", + "--setup", + "--yes", + "--no-start", + "--no-browser", + "--family", + family, + "--model", + q.id, + "--context", + "131072", + "--vision", + "gpu", + "--cuda", + "12", + "--prebuilt", + &pre_s, + "--data-dir", + &self.paths.data_dir().to_string_lossy(), + "--gpu", + &env.main.to_string(), + "--low-ram", + "off", + ] + .iter() + .map(|s| s.to_string()) + .collect(); + let extra = [ + ("CUDA_DEVICE_ORDER", "PCI_BUS_ID".to_string()), + ("PYTHONUNBUFFERED", "1".to_string()), + ( + "XDG_CACHE_HOME", + home.join("cache").to_string_lossy().into_owned(), + ), + ]; + if let Err(e) = self.run_logged(&log, &src_dir, "bash", &args, &extra).await { + return b + .jobs + .fail( + store, + &format!("l'installation a échoué : {e} (voir le journal)"), + ) + .await; + } + let _ = std::fs::write(self.paths.engine_marker(), format!("{ENGINE_ASSET}\n")); + let cfg_path = match find_config(&src_dir, q.id) { + Ok(p) => p, + Err(e) => return b.jobs.fail(store, &e).await, + }; + let name = preset_name(family, q.id); + let presets = self.paths.presets_dir(); + let preset = presets.join(format!("{name}.env")); + let body = [ + format!("# NAME={} {} (Strata)", family_label(family), q.id), + format!("ENGINE={ENGINE_STRATA}"), + format!("STRATA_CONFIG={cfg_path}"), + format!("STRATA_MAIN_GPU={}", env.main), + format!("STRATA_HELPER_GPU={}", env.helper), + "STRATA_VISION=1".into(), + format!("STRATA_EXPERTS={EXPERTS_AUTO}"), + "STRATA_DROP=1".into(), + "STRATA_KV=fp16".into(), + "STRATA_KV_RESIDENT=32768".into(), + "STRATA_SPEC=3".into(), + "CTX=131072".into(), + "REASONING=off".into(), + String::new(), + ] + .join("\n"); + if let Err(e) = std::fs::create_dir_all(&presets) { + return b + .jobs + .fail( + store, + &crate::paths::os_err("mkdir", &presets.to_string_lossy(), &e), + ) + .await; + } + if let Err(e) = std::fs::write(&preset, body) { + return b + .jobs + .fail( + store, + &crate::paths::os_err("open", &preset.to_string_lossy(), &e), + ) + .await; + } + log.phase("activation du modèle (premier chargement : quelques minutes)…") + .await; + if let Err(e) = switch(store, &preset).await { + return b + .jobs + .fail( + store, + &format!("modèle installé mais bascule impossible : {e}"), + ) + .await; + } + b.jobs + .done( + store, + &format!("{} {} installé (Strata)", family_label(family), q.id), + ) + .await; + } +} + +/// `SwitchToPreset` : le garde de l'optimiseur, puis l'application et le +/// redémarrage par le Go. +async fn switch(store: &Store, path: &Path) -> Result<(), String> { + if let Some(e) = crate::backends::tune_busy(store).await { + return Err(e); + } + crate::presets_api::preset_apply(store, path, "switch").await +} + +/// Le `sinkWriter` du Go : un flux découpé en lignes ; une barre qui se +/// redessine (`\r`) n'est montrée que toutes les 10 s. +#[derive(Default)] +pub struct SinkWriter { + buf: Vec, + last_prog: Option, +} + +/// `sinkProgressEvery`. +const PROGRESS_EVERY: Duration = Duration::from_secs(10); + +impl SinkWriter { + pub fn write(&mut self, p: &[u8]) -> Vec { + self.buf.extend_from_slice(p); + let mut out = Vec::new(); + while let Some(i) = self.buf.iter().position(|c| *c == b'\r' || *c == b'\n') { + if self.buf[i] == b'\n' { + let line = String::from_utf8_lossy(&self.buf[..i]).into_owned(); + out.push(line.trim_end_matches('\r').to_string()); + self.buf.drain(..=i); + continue; + } + if i + 1 >= self.buf.len() { + break; + } + if self.buf[i + 1] == b'\n' { + out.push(String::from_utf8_lossy(&self.buf[..i]).into_owned()); + self.buf.drain(..i + 2); + continue; + } + let prog = String::from_utf8_lossy(&self.buf[..i]).trim().to_string(); + if !prog.is_empty() && self.last_prog.is_none_or(|t| t.elapsed() >= PROGRESS_EVERY) { + self.last_prog = Some(Instant::now()); + out.push(prog); + } + self.buf.drain(..=i); + } + out + } +} + +/// Les routes servies par ce module. +pub fn handles(path: &str) -> bool { + matches!( + path, + "/api/strata" | "/api/strata/install" | "/api/strata/settings" + ) +} + +fn fail(code: StatusCode, e: impl Into) -> Response { + send_json(code, &json!({ "ok": false, "error": e.into() })) +} + +/// `from_go` : remise par le Go (tunnel), déjà authentifiée par lui. +pub async fn serve( + ctx: &Ctx, + s: &Arc, + req: Request, + from_go: bool, +) -> Response { + let Some(b) = ctx.backends.clone() else { + return fail( + StatusCode::SERVICE_UNAVAILABLE, + "backends non tenus par la façade", + ); + }; + let (parts, body) = req.into_parts(); + if !from_go && let Err(refus) = ctx.guard(&parts.headers).await { + return *refus; + } + let raw = Limited::new(body, 1 << 20) + .collect() + .await + .map(|b| b.to_bytes().to_vec()) + .unwrap_or_default(); + let store = &ctx.store; + let post = parts.method == Method::POST; + match parts.uri.path() { + "/api/strata" => send_json(StatusCode::OK, &s.overview(store).await), + "/api/strata/settings" => { + if !post { + return fail(StatusCode::METHOD_NOT_ALLOWED, "POST attendu"); + } + let d = gojson::decode_struct( + &raw, + SETTINGS_REQ, + &[ + ("preset", Kind::Str), + ("ctx", Kind::Int), + ("kv", Kind::Str), + ("spec", Kind::Int), + ("vision", Kind::Bool), + ("helper", Kind::Bool), + ("experts", Kind::Str), + ], + ); + if let Some(e) = d.err.clone() { + return fail(StatusCode::BAD_REQUEST, e); + } + let r = SettingsReq { + preset: d.str("preset"), + ctx: d.int("ctx"), + kv: d.str("kv"), + spec: d.int("spec"), + vision: d.bool("vision"), + helper: d.bool("helper"), + experts: d.str("experts"), + }; + if r.preset.contains(['/', '\\']) || r.preset.is_empty() { + return fail(StatusCode::BAD_REQUEST, "preset invalide"); + } + let home = &s.paths.home; + let content = match crate::presets_api::read_preset(home, &r.preset) { + Ok(c) if is_strata(&crate::presets::parse_env(&c)) => c, + _ => return fail(StatusCode::NOT_FOUND, "modèle introuvable"), + }; + let next = match apply_settings(&content, &r) { + Ok(n) => n, + Err(e) => return fail(StatusCode::BAD_REQUEST, e), + }; + // « En service » se décide AVANT l'écriture (comme save_applying) : + // c'est l'ancien contenu qui porte l'empreinte de la configuration. + let cfg = store.config().await; + let order = crate::presets::parse_preset_order( + store + .get(BK_STATE, crate::presets::PRESET_ORDER_KEY) + .await + .ok() + .flatten() + .as_deref(), + ); + let active = crate::presets::list_presets(home, &cfg, &order) + .is_ok_and(|l| l.iter().any(|p| p.id == r.preset && p.active)); + let path = s.paths.presets_dir().join(format!("{}.env", r.preset)); + if let Err(e) = std::fs::write(&path, next) { + return fail( + StatusCode::INTERNAL_SERVER_ERROR, + crate::paths::os_err("open", &path.to_string_lossy(), &e), + ); + } + let mut restarted = false; + if active { + if let Some(e) = crate::backends::tune_busy(store).await { + return send_json( + StatusCode::CONFLICT, + &json!({ "ok": false, "tuning": true, "error": e }), + ); + } + if let Err(e) = crate::presets_api::preset_apply(store, &path, "switch").await { + return fail(StatusCode::INTERNAL_SERVER_ERROR, e); + } + restarted = true; + } + send_json( + StatusCode::OK, + &json!({ "ok": true, "restarted": restarted }), + ) + } + "/api/strata/install" => { + if !post { + return fail(StatusCode::METHOD_NOT_ALLOWED, "POST attendu"); + } + let d = gojson::decode_struct( + &raw, + INSTALL_REQ, + &[("family", Kind::Str), ("quant", Kind::Str)], + ); + if let Some(e) = d.err.clone() { + return fail(StatusCode::BAD_REQUEST, e); + } + let (family, q) = (d.str("family"), d.str("quant")); + if !FAMILIES + .iter() + .any(|f| f.id == family && f.quants.contains(&q.as_str())) + { + return fail(StatusCode::BAD_REQUEST, "version ou quant inconnu"); + } + if let Some(err) = crate::backends::tune_busy(store).await { + return fail(StatusCode::CONFLICT, err); + } + if let Err(err) = b.jobs.start(store, "strata").await { + return fail(StatusCode::CONFLICT, err); + } + let (ctx2, s2, b2) = (ctx.clone(), s.clone(), b.clone()); + tokio::spawn(async move { + s2.run_install(&ctx2, &b2, &family, &q).await; + b2.jobs.end(&ctx2.store).await; + }); + send_json(StatusCode::OK, &json!({ "ok": true })) + } + _ => fail(StatusCode::NOT_FOUND, "route inconnue"), + } +} diff --git a/rust/loki-rs/src/strata/mod.rs b/rust/loki-rs/src/strata/mod.rs new file mode 100644 index 0000000..6dd50b3 --- /dev/null +++ b/rust/loki-rs/src/strata/mod.rs @@ -0,0 +1,848 @@ +//! Strata, deuxième moteur de Loki (lot 25 de la migration, +//! `LOKI_STRATA=rust` ; expérimental, le Go reste le défaut) — port de +//! `backend_strata.go`. +//! +//! Strata répartit les experts d'un MoE de 125 B (famille Qwen3.8-Flash-Next) +//! entre VRAM, RAM et disque. Le moteur est le paquet FIGÉ publié par AJEAN +//! (sources + binaire Linux CUDA 12, vérifiés par SHA-256) ; le choix se fait +//! par preset (`ENGINE=strata`). +//! +//! Ici : la décision pure (placement des experts, configuration de lancement, +//! ce qui tient sur la machine, recommandation, réglages), la machine (cartes, +//! RAM, disque, Python) et les chemins. Les routes et l'installation sont dans +//! [`api`]. + +pub mod api; + +use std::collections::HashMap; +use std::path::{Path, PathBuf}; + +use serde_json::{Map, Value, json}; + +/// Paquet figé (release moe-v1.0 d'AJEAN). +pub const VERSION: &str = "1.0"; +pub const RELEASE_BASE: &str = "https://github.com/nathaninline/ajean/releases/download/moe-v1.0/"; +pub const SRC_ASSET: &str = "ajean-moe-src-1.0.tar.gz"; +pub const ENGINE_ASSET: &str = "ajean-moe-engine-1.0-linux-x64-cuda12.zip"; +/// Le nom sous lequel l'installeur attend le moteur (CUDA12_ASSET). +pub const ENGINE_LOCAL: &str = "strata-linux-x64-cuda12.zip"; + +/// `strataAssetSHA`. +pub fn default_asset_sha() -> HashMap { + HashMap::from([ + ( + SRC_ASSET.to_string(), + "5747f69426973d957e4f9894a8e3333c6ef0d6ac8565e26ddb8d36f52211cb3b".to_string(), + ), + ( + ENGINE_ASSET.to_string(), + "b5851bc138ab32ca3ffefc16bf91c8f557e4d503503473a22f2b6c9e9b8fd34c".to_string(), + ), + ]) +} + +pub const ENGINE_LLAMACPP: &str = "llamacpp"; +pub const ENGINE_STRATA: &str = "strata"; + +pub type Cfg = HashMap; + +fn cfg_get<'a>(cfg: &'a Cfg, k: &str) -> &'a str { + cfg.get(k).map_or("", String::as_str) +} + +/// `engineOf` : « moe » est accepté pour un preset recopié d'AJEAN. +pub fn engine_of(cfg: &Cfg) -> &'static str { + match cfg_get(cfg, "ENGINE").trim().to_lowercase().as_str() { + ENGINE_STRATA | "moe" => ENGINE_STRATA, + _ => ENGINE_LLAMACPP, + } +} + +/// `isStrataConfig`. +pub fn is_strata(cfg: &Cfg) -> bool { + engine_of(cfg) == ENGINE_STRATA +} + +/// `strataFamily`. +pub struct Family { + pub id: &'static str, + pub label: &'static str, + pub about: &'static str, + pub quants: &'static [&'static str], +} + +/// `strataQuant`. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Quant { + pub id: &'static str, + pub about: &'static str, + pub download_gb: f64, + pub arena_gb: f64, +} + +impl Quant { + fn to_json(self) -> Value { + json!({ + "id": self.id, "about": self.about, + "download_gb": go_num(self.download_gb), "arena_gb": go_num(self.arena_gb), + }) + } +} + +pub const FAMILIES: &[Family] = &[ + Family { + id: "swift", + label: "Swift 1.5", + about: "réfléchit moins, répond plus vite", + quants: &["IQ2_XS", "IQ3_XXS"], + }, + Family { + id: "qwen", + label: "Classique", + about: "le Qwen3.8-Flash-Next original", + quants: &["Q2_0", "IQ2_XS", "IQ3_XXS", "IQ3_S"], + }, +]; + +const QUANTS: &[Quant] = &[ + Quant { + id: "Q2_0", + about: "le plus rapide", + download_gb: 66.4, + arena_gb: 34.0, + }, + Quant { + id: "IQ2_XS", + about: "un peu plus fidèle, presque aussi rapide", + download_gb: 68.0, + arena_gb: 35.5, + }, + Quant { + id: "IQ3_XXS", + about: "99 % de la qualité du modèle complet", + download_gb: 75.8, + arena_gb: 42.9, + }, + Quant { + id: "IQ3_S", + about: "la meilleure qualité, le plus lent", + download_gb: 83.6, + arena_gb: 50.3, + }, +]; + +/// `strataQuants[id]`. +pub fn quant(id: &str) -> Option { + QUANTS.iter().find(|q| q.id == id).copied() +} + +pub const LOW_RAM_HEADROOM_GB: f64 = 10.0; +pub const DROP_HEADROOM_GB: f64 = 7.0; + +/// `strataHelperExpertsGB`. +pub fn helper_experts_gb(vram_gb: f64) -> f64 { + (vram_gb - 2.5).max(0.0) +} + +pub const EXPERTS_AUTO: &str = "auto"; +pub const EXPERTS_RAM: &str = "ram"; +pub const EXPERTS_DISK: &str = "disk"; + +/// `strataMaxCtx`. +pub const MAX_CTX: i64 = 262144; +/// `strataMinArch`. +pub const MIN_ARCH: i64 = 75; +/// `strataLaunchModeKey` (bkState). +pub const LAUNCH_MODE_KEY: &str = "strata_experts_mode"; +/// `strataServeMarker`. +pub const SERVE_MARKER: &str = "[loki serve] Strata"; + +/// Un nombre comme le Go l'écrit en JSON (entier sans « .0 »). +pub fn go_num(f: f64) -> Value { + if f.fract() == 0.0 && f.abs() < 1e15 { + json!(f as i64) + } else { + json!(f) + } +} + +/// `fmt.Sprint` d'une valeur JSON décodée par le Go (`any`). +pub fn go_sprint(v: &Value) -> String { + match v { + Value::String(s) => s.clone(), + Value::Number(n) => go_g(n.as_f64().unwrap_or(0.0)), + Value::Bool(b) => b.to_string(), + Value::Null => "".into(), + Value::Array(a) => format!( + "[{}]", + a.iter().map(go_sprint).collect::>().join(" ") + ), + Value::Object(m) => format!( + "map[{}]", + m.iter() + .map(|(k, v)| format!("{k}:{}", go_sprint(v))) + .collect::>() + .join(" ") + ), + } +} + +/// `strconv.FormatFloat(f, 'g', -1, 64)` (le `%v` d'un float64) : le plus +/// court, en notation exponentielle hors de [1e-4, 1e6[. +pub fn go_g(f: f64) -> String { + if f.is_nan() { + return "NaN".into(); + } + if f.is_infinite() { + return if f > 0.0 { "+Inf" } else { "-Inf" }.into(); + } + if f == 0.0 { + return if f.is_sign_negative() { "-0" } else { "0" }.into(); + } + let e = format!("{f:e}"); + let (mant, exp) = e.split_once('e').unwrap_or((&e, "0")); + let exp: i32 = exp.parse().unwrap_or(0); + if !(-4..6).contains(&exp) { + let sign = if exp < 0 { '-' } else { '+' }; + return format!("{mant}e{sign}{:02}", exp.abs()); + } + format!("{f}") +} + +// --------------------------------------------------------------------------- +// Chemins +// --------------------------------------------------------------------------- + +/// Les chemins de Strata sous `$LOKI_HOME`. +#[derive(Clone, Debug)] +pub struct Paths { + pub home: PathBuf, +} + +impl Paths { + pub fn strata_home(&self) -> PathBuf { + self.home.join("strata") + } + pub fn src_dir(&self) -> PathBuf { + self.strata_home().join(format!("ajean-moe-{VERSION}")) + } + pub fn data_dir(&self) -> PathBuf { + self.strata_home().join("data") + } + pub fn dl_dir(&self) -> PathBuf { + self.strata_home().join("dl") + } + pub fn presets_dir(&self) -> PathBuf { + self.home.join("presets") + } + /// `strataEngineMarker` : le paquet dont vient le moteur installé. + pub fn engine_marker(&self) -> PathBuf { + self.src_dir().join("engine-cuda12").join(".loki-engine") + } + /// `strataEngineInstalled`. + pub fn engine_installed(&self) -> String { + std::fs::read_to_string(self.engine_marker()) + .map(|s| s.trim().to_string()) + .unwrap_or_default() + } +} + +// --------------------------------------------------------------------------- +// Experts +// --------------------------------------------------------------------------- + +/// `strataConfigTag` : strata-swift-iq3_xxs.json → swift-iq3_xxs. +pub fn config_tag(path: &str) -> String { + let b = crate::paths::go_base(path); + let b = b.strip_suffix(".json").unwrap_or(&b); + match b.find('-') { + Some(i) => b[i + 1..].to_string(), + None => b.to_string(), + } +} + +/// `strataArenaGB` : la taille des experts du quant d'un preset (0 = inconnu). +pub fn arena_gb(cfg: &Cfg) -> f64 { + let tag = config_tag(cfg_get(cfg, "STRATA_CONFIG").trim()).to_uppercase(); + let tag = tag.strip_prefix("SWIFT-").unwrap_or(&tag); + quant(tag).map_or(0.0, |q| q.arena_gb) +} + +/// `strataPackHasExpertsBin`. +pub fn pack_has_experts_bin(args: &[String]) -> bool { + args.windows(2) + .any(|w| w[0] == "--pack" && Path::new(&w[1]).join("experts.bin").exists()) +} + +/// `strataHelperOn` : la carte d'aide existe et n'a pas été coupée. +pub fn helper_on(cfg: &Cfg) -> bool { + let h = cfg_get(cfg, "STRATA_HELPER_GPU").trim(); + !h.is_empty() && h != "-1" && cfg_get(cfg, "STRATA_HELPER") != "0" +} + +/// `strataResolveExperts` : le mode lancé (drop, ram, arena, disk), d'après +/// le choix du preset et la RAM disponible. +pub fn resolve_experts( + paths: &Paths, + cfg: &Cfg, + args: &[String], + avail_gb: f64, + helper_gb: f64, +) -> &'static str { + let bin_ready = pack_has_experts_bin(args) && paths.engine_installed() == ENGINE_ASSET; + let drop_ready = bin_ready && helper_on(cfg) && cfg_get(cfg, "STRATA_DROP") != "0"; + let arena = arena_gb(cfg); + match cfg_get(cfg, "STRATA_EXPERTS") + .trim() + .to_lowercase() + .as_str() + { + EXPERTS_DISK => return if bin_ready { "arena" } else { "disk" }, + EXPERTS_RAM => return if drop_ready { "drop" } else { "ram" }, + _ => {} + } + if arena <= 0.0 { + return "disk"; + } + if drop_ready && avail_gb >= arena - helper_experts_gb(helper_gb) + DROP_HEADROOM_GB { + return "drop"; + } + if avail_gb >= arena + LOW_RAM_HEADROOM_GB { + return "ram"; + } + if bin_ready { "arena" } else { "disk" } +} + +/// `strataExpertsLabel`. +pub fn experts_label(mode: &str) -> String { + match mode { + "drop" => "verrouillés en RAM, hors ceux de la carte d'appoint".into(), + "ram" => "chargés et verrouillés en RAM".into(), + "arena" => "experts.bin mappé (cache système)".into(), + "disk" => "lus depuis le disque (mmap)".into(), + m => m.into(), + } +} + +// --------------------------------------------------------------------------- +// Configuration de lancement +// --------------------------------------------------------------------------- + +/// `strataTuning` (ordre des clés de la map Go, itérée au hasard mais +/// idempotente : chaque drapeau est posé une fois). +const TUNING: [(&str, &str); 3] = [ + ("--prefill", "16384"), + ("--short-read", "150"), + ("--prompt-cache-root", "256"), +]; + +/// `strataEnvTuning`. +const ENV_TUNING: [(&str, &str); 2] = [("STRATA_PLE_BATCH", "0"), ("STRATA_NO_LARGEPAGES", "1")]; + +/// `strataSetArg`. +pub fn set_arg(mut args: Vec, flag: &str, value: &str) -> Vec { + for i in 0..args.len().saturating_sub(1) { + if args[i] == flag { + args[i + 1] = value.to_string(); + return args; + } + } + args.push(flag.to_string()); + args.push(value.to_string()); + args +} + +/// `strataDropFlag` : retire un drapeau SANS valeur. +pub fn drop_flag(args: Vec, flag: &str) -> Vec { + args.into_iter().filter(|a| a != flag).collect() +} + +/// `strataDropFlagValue` : retire un drapeau ET sa valeur. +pub fn drop_flag_value(args: Vec, flag: &str) -> Vec { + let mut out = Vec::new(); + let mut i = 0; + while i < args.len() { + if args[i] == flag { + i += 2; + continue; + } + out.push(args[i].clone()); + i += 1; + } + out +} + +/// `strataHasArg`. +pub fn has_arg(args: &[String], flag: &str) -> bool { + args.iter().any(|a| a == flag) +} + +/// `strataArgList`. +pub fn arg_list(cfg: &Value) -> Vec { + cfg.get("args") + .and_then(Value::as_array) + .map(|l| l.iter().map(go_sprint).collect()) + .unwrap_or_default() +} + +fn first_non_empty<'a>(a: &'a str, b: &'a str) -> &'a str { + if a.is_empty() { b } else { a } +} + +/// `strataBuildConfig` : la config de l'installeur avec les réglages du +/// preset et les experts placés selon `mode`. Pure. +pub fn build_config(base: &Value, cfg: &Cfg, api_key: &str, mode: &str) -> Result { + let mut out: Map = match base { + Value::Object(m) => m.clone(), + _ => Map::new(), + }; + if !out.get("args").is_some_and(Value::is_array) { + return Err("configuration de Strata sans « args »".into()); + } + let mut args = arg_list(&Value::Object(out.clone())); + for (flag, v) in TUNING { + args = set_arg(args, flag, v); + } + let helper = cfg_get(cfg, "STRATA_HELPER_GPU").trim(); + let has_helper = helper_on(cfg); + if has_helper { + args = set_arg(args, "--expert-cache-device1", "auto"); + if !has_arg(&args, "--remote-expert-opt") { + args.push("--remote-expert-opt".into()); + } + out.remove("gpu"); + args = drop_flag_value(args, "--vram-reserve-mib"); + if let Some(Value::Object(v)) = out.get_mut("vision") + && let Ok(n) = helper.parse::() + { + v.insert("cuda_device".into(), json!(n)); + } + } + let mut env: Map = match out.get("env") { + Some(Value::Object(e)) => e.clone(), + _ => Map::new(), + }; + args = drop_flag(drop_flag(args, "--mmap-experts"), "--resident-experts"); + env.remove("STRATA_ARENA_MMAP"); + env.remove("STRATA_REMOTE_DROP"); + match mode { + "drop" if has_helper => { + args = drop_flag_value(args, "--pcie-frac"); + env.insert("STRATA_REMOTE_DROP".into(), json!("1")); + env.insert("STRATA_STAGER_THREADS".into(), json!("8")); + env.insert("STRATA_STAGER_RING".into(), json!("32")); + } + "arena" => { + args = set_arg(args, "--pcie-frac", "0"); + env.insert("STRATA_ARENA_MMAP".into(), json!("1")); + } + "disk" => { + args.push("--mmap-experts".into()); + args = set_arg(args, "--pcie-frac", "0"); + } + _ => {} + } + for (k, v) in ENV_TUNING { + env.insert(k.into(), json!(v)); + } + out.insert("env".into(), Value::Object(env)); + let ctx = cfg_get(cfg, "CTX").trim(); + if !ctx.is_empty() { + args = set_arg(args, "--max-context", ctx); + } + for (key, flag) in [ + ("STRATA_KV", "--kv"), + ("STRATA_SPEC", "--spec"), + ("STRATA_KV_RESIDENT", "--kv-resident"), + ] { + let v = cfg_get(cfg, key).trim(); + if !v.is_empty() { + args = set_arg(args, flag, v); + } + } + if cfg_get(cfg, "STRATA_VISION") == "0" { + args = drop_flag(args, "--vision"); + out.remove("vision"); + } + out.insert( + "args".into(), + Value::Array(args.into_iter().map(Value::String).collect()), + ); + let port = first_non_empty(cfg_get(cfg, "PORT"), "8080") + .parse::() + .unwrap_or(0); + out.insert("port".into(), json!(port)); + out.insert( + "host".into(), + json!(first_non_empty(cfg_get(cfg, "HOST"), "127.0.0.1")), + ); + if !api_key.is_empty() { + out.insert("api_key".into(), json!(api_key)); + } + Ok(Value::Object(out)) +} + +/// `strataCudaDevices` : la principale en CUDA0. +pub fn cuda_devices(cfg: &Cfg) -> String { + let main = cfg_get(cfg, "STRATA_MAIN_GPU").trim(); + if main.is_empty() || main == "-1" { + return String::new(); + } + if helper_on(cfg) { + format!("{main},{}", cfg_get(cfg, "STRATA_HELPER_GPU").trim()) + } else { + main.to_string() + } +} + +/// `strataPreflight` : ce qu'il faut pour lancer Strata. +pub fn preflight(cfg: &Cfg) -> Result<(), String> { + let path = cfg_get(cfg, "STRATA_CONFIG").trim(); + if path.is_empty() { + return Err( + "STRATA_CONFIG non défini : réinstalle le modèle depuis Paramètres → Moteur → Strata" + .into(), + ); + } + if std::fs::metadata(path).is_err() { + return Err(format!( + "configuration de Strata introuvable : {path} — réinstalle le modèle" + )); + } + let py = Path::new(&crate::paths::go_dir(path)) + .join(".venv") + .join("bin") + .join("python"); + if std::fs::metadata(&py).is_err() { + return Err(format!( + "environnement Python de Strata absent ({}) : réinstalle le modèle", + py.to_string_lossy() + )); + } + Ok(()) +} + +// --------------------------------------------------------------------------- +// Machine +// --------------------------------------------------------------------------- + +/// `strataGPU`. +#[derive(Clone, Debug, PartialEq)] +pub struct Gpu { + pub index: i64, + pub name: String, + pub vram_gb: f64, + pub arch: i64, +} + +impl Gpu { + fn to_json(&self) -> Value { + json!({ "index": self.index, "name": self.name, "vram_gb": go_num(self.vram_gb), "arch": self.arch }) + } +} + +/// `strataEnv`. +#[derive(Clone, Debug, PartialEq)] +pub struct Env { + pub supported: bool, + pub reason: String, + pub gpus: Vec, + pub main: i64, + pub helper: i64, + pub ram_gb: f64, + pub avail_gb: f64, + pub disk_free_gb: f64, + pub python: String, +} + +impl Default for Env { + fn default() -> Self { + Env { + supported: false, + reason: String::new(), + gpus: Vec::new(), + main: -1, + helper: -1, + ram_gb: 0.0, + avail_gb: 0.0, + disk_free_gb: 0.0, + python: String::new(), + } + } +} + +impl Env { + pub fn to_json(&self) -> Value { + let mut v = json!({ + "supported": self.supported, + "gpus": if self.gpus.is_empty() { Value::Null } else { Value::Array(self.gpus.iter().map(Gpu::to_json).collect()) }, + "main": self.main, "helper": self.helper, + "ram_gb": go_num(self.ram_gb), "avail_gb": go_num(self.avail_gb), + "disk_free_gb": go_num(self.disk_free_gb), + }); + if !self.reason.is_empty() { + v["reason"] = json!(self.reason); + } + if !self.python.is_empty() { + v["python"] = json!(self.python); + } + v + } +} + +/// `strataTag` : « swift-IQ3_XXS », « IQ3_XXS ». +pub fn tag(family: &str, quant: &str) -> String { + if family == "swift" { + format!("swift-{quant}") + } else { + quant.to_string() + } +} + +/// `strataDirGB` : la taille des fichiers d'un dossier, en Go. +pub fn dir_gb(dir: &Path) -> f64 { + fn walk(p: &Path) -> u64 { + let Ok(rd) = std::fs::read_dir(p) else { + return 0; + }; + let mut t = 0; + for e in rd.flatten() { + let Ok(ft) = e.file_type() else { continue }; + if ft.is_dir() { + t += walk(&e.path()); + } else if ft.is_file() { + t += e.metadata().map_or(0, |m| m.len()); + } + } + t + } + walk(dir) as f64 / 1e9 +} + +/// `strataHaveGB` : ce qui est déjà sur le disque pour CE choix. +pub fn have_gb(paths: &Paths, family: &str, quant: &str) -> f64 { + let t = tag(family, quant); + let data = paths.data_dir(); + dir_gb(&data.join("models").join(&t)) + + dir_gb(&data.join("packs").join(t.to_lowercase())) + + dir_gb(&data.join("mtp")) +} + +/// `strataFit`. +#[derive(Clone, Debug, PartialEq)] +pub struct Fit { + pub quant: Quant, + pub disk_gb: f64, + pub mmap: bool, + pub drop: bool, + pub ok: bool, + pub why: String, + pub preset: String, + pub active: bool, + pub details: Option, +} + +impl Fit { + pub fn to_json(&self) -> Value { + let mut v = json!({ + "quant": self.quant.to_json(), "disk_gb": go_num(self.disk_gb), + "mmap": self.mmap, "drop": self.drop, "ok": self.ok, + }); + if !self.why.is_empty() { + v["why"] = json!(self.why); + } + if !self.preset.is_empty() { + v["preset"] = json!(self.preset); + } + if self.active { + v["active"] = json!(true); + } + if let Some(d) = &self.details { + v["details"] = d.clone(); + } + v + } +} + +/// `%.0f` du Go (arrondi au plus proche, demi vers le pair). +pub fn f0(x: f64) -> String { + format!("{x:.0}") +} + +/// `strataFitFor` : ce qu'un quant demande sur cette machine, et s'il y tient. +pub fn fit_for(q: Quant, env: &Env, have: f64) -> Fit { + let mut f = Fit { + quant: q, + disk_gb: (q.download_gb - have).max(10.0), + mmap: env.avail_gb < q.arena_gb + LOW_RAM_HEADROOM_GB, + drop: false, + ok: false, + why: String::new(), + preset: String::new(), + active: false, + details: None, + }; + let vram: f64 = env + .gpus + .iter() + .filter(|g| g.index == env.main || g.index == env.helper) + .map(|g| g.vram_gb) + .sum(); + if env.ram_gb + vram - 12.0 < q.arena_gb { + f.why = format!( + "demande plus de mémoire : {} Go de RAM + VRAM, il en faut ~{}", + f0(env.ram_gb + vram), + f0(q.arena_gb + 12.0) + ); + } else if env.disk_free_gb > 0.0 && env.disk_free_gb < f.disk_gb + 5.0 { + f.why = format!( + "pas assez d'espace disque : {} Go libres, il en faut ~{}", + f0(env.disk_free_gb), + f0(f.disk_gb + 5.0) + ); + } else { + f.ok = true; + } + f +} + +/// `strataRecommend` : le quant le plus fidèle qui tient. +pub fn recommend(paths: &Paths, family: &str, env: &Env) -> String { + let Some(fam) = FAMILIES.iter().find(|f| f.id == family) else { + return String::new(); + }; + let mut best = String::new(); + for id in ["IQ3_XXS", "IQ2_XS", "Q2_0"] { + if !fam.quants.contains(&id) { + continue; + } + let q = quant(id).expect("quant"); + if fit_for(q, env, have_gb(paths, family, id)).ok { + best = id.to_string(); + break; + } + } + if fam.quants.contains(&"IQ3_S") { + let q = quant("IQ3_S").expect("quant"); + let f = fit_for(q, env, have_gb(paths, family, "IQ3_S")); + if f.ok && !f.mmap { + best = "IQ3_S".into(); + } + } + best +} + +/// `strataPresetName`. +pub fn preset_name(family: &str, quant: &str) -> String { + let label = if family == "swift" { + "Swift 1.5" + } else { + "Classique" + }; + format!("STRATA FLASH NEXT {} {quant}", label.to_uppercase()) +} + +/// `strataFamilyLabel`. +pub fn family_label(id: &str) -> String { + match FAMILIES.iter().find(|f| f.id == id) { + Some(f) if f.id == "qwen" => "Qwen3.8 Flash Next".into(), + Some(f) => format!("Qwen3.8 Flash Next {}", f.label), + None => id.into(), + } +} + +/// `strataBool`. +pub fn sbool(b: bool) -> &'static str { + if b { "1" } else { "0" } +} + +/// `strataSettingsReq`. +#[derive(Clone, Debug, Default)] +pub struct SettingsReq { + pub preset: String, + pub ctx: i64, + pub kv: String, + pub spec: i64, + pub vision: bool, + pub helper: bool, + pub experts: String, +} + +/// `strataApplySettings` : réécrit les clés du preset. Pure. +pub fn apply_settings(content: &str, r: &SettingsReq) -> Result { + if r.ctx < 32768 || r.ctx > MAX_CTX || r.ctx % 4096 != 0 { + return Err(format!("contexte hors limites : {}", r.ctx)); + } + if r.kv != "fp16" && r.kv != "int8" { + return Err(format!("cache KV inconnu : {}", r.kv)); + } + if r.spec < 2 || r.spec > 4 { + return Err(format!("MTP hors limites : {}", r.spec)); + } + if !r.experts.is_empty() + && r.experts != EXPERTS_AUTO + && r.experts != EXPERTS_RAM + && r.experts != EXPERTS_DISK + { + return Err(format!("placement des experts inconnu : {}", r.experts)); + } + let mut set: Vec<(&str, String)> = vec![ + ("CTX", r.ctx.to_string()), + ("STRATA_KV", r.kv.clone()), + ("STRATA_SPEC", r.spec.to_string()), + ("STRATA_VISION", sbool(r.vision).into()), + ("STRATA_HELPER", sbool(r.helper).into()), + ]; + if !r.experts.is_empty() { + set.push(("STRATA_EXPERTS", r.experts.clone())); + } + let mut lines: Vec = Vec::new(); + for l in content.trim_end_matches('\n').split('\n') { + let k = l.trim().split_once('=').map_or(l.trim(), |(k, _)| k); + if set.iter().any(|(s, _)| *s == k) { + continue; + } + lines.push(l.to_string()); + } + for (k, v) in set { + lines.push(format!("{k}={v}")); + } + Ok(lines.join("\n") + "\n") +} + +/// `strataHelperVRAM` : VRAM de la carte d'appoint du preset, 0 sans. +pub fn helper_vram(cfg: &Cfg, gpus: &[Gpu]) -> f64 { + if !helper_on(cfg) { + return 0.0; + } + let h = cfg_get(cfg, "STRATA_HELPER_GPU").trim(); + gpus.iter() + .find(|g| g.index.to_string() == h) + .map_or(0.0, |g| g.vram_gb) +} + +/// `strataFindConfig` : la config que l'installeur a écrite pour ce quant. +pub fn find_config(src_dir: &Path, quant: &str) -> Result { + let q = quant.to_lowercase(); + let mut names: Vec = std::fs::read_dir(src_dir) + .map(|rd| { + rd.flatten() + .map(|e| e.file_name().to_string_lossy().into_owned()) + .filter(|n| n.starts_with("strata-") && n.ends_with(".json")) + .collect() + }) + .unwrap_or_default(); + names.sort(); + for n in names { + if n.to_lowercase().contains(&q) { + return Ok(src_dir.join(n).to_string_lossy().into_owned()); + } + } + Err(format!( + "l'installeur n'a pas laissé de configuration pour {quant} dans {}", + src_dir.to_string_lossy() + )) +} + +#[cfg(test)] +mod tests; diff --git a/rust/loki-rs/src/strata/tests.rs b/rust/loki-rs/src/strata/tests.rs new file mode 100644 index 0000000..47a6376 --- /dev/null +++ b/rust/loki-rs/src/strata/tests.rs @@ -0,0 +1,485 @@ +//! Les tests du Go (`backend_strata_test.go`), portés. + +use super::*; + +fn cfg(kv: &[(&str, &str)]) -> Cfg { + kv.iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect() +} + +fn args_of(v: &Value) -> Vec { + arg_list(v) +} + +fn arg_after(args: &[String], flag: &str) -> String { + args.windows(2) + .find(|w| w[0] == flag) + .map(|w| w[1].clone()) + .unwrap_or_default() +} + +#[test] +fn reglages_valides_appliques() { + let base = json!({ + "exe": "/x/engine-cuda12/strata", + "args": ["--pack", "/p", "--prefill", "8192", "--max-context", "131072"], + "port": 8080.0, + }); + let out = build_config( + &base, + &cfg(&[("PORT", "8081"), ("CTX", "65536")]), + "k", + "ram", + ) + .unwrap(); + let a = args_of(&out); + for (flag, want) in [ + ("--prefill", "16384"), + ("--short-read", "150"), + ("--prompt-cache-root", "256"), + ("--max-context", "65536"), + ("--pack", "/p"), + ] { + assert_eq!(arg_after(&a, flag), want, "{flag} : {a:?}"); + } + assert_eq!(a.join(" ").matches("--prefill").count(), 1); + assert!(!has_arg(&a, "--remote-expert-opt") && !has_arg(&a, "--expert-cache-device1")); + assert_eq!(out["port"], 8081); + assert_eq!(out["api_key"], "k"); + assert_eq!(out["host"], "127.0.0.1"); + assert_eq!(base["args"][3], "8192", "la config de base est modifiée"); +} + +#[test] +fn carte_d_aide() { + let base = json!({ + "args": ["--pack", "/p", "--mmap-experts", "--vram-reserve-mib", "700"], + "gpu": 1.0, + "vision": { "exe": "v", "gpu": true }, + }); + let out = build_config(&base, &cfg(&[("STRATA_HELPER_GPU", "0")]), "", "ram").unwrap(); + let a = args_of(&out); + assert_eq!(arg_after(&a, "--expert-cache-device1"), "auto"); + assert!(has_arg(&a, "--remote-expert-opt")); + assert!(!has_arg(&a, "--vram-reserve-mib") && !has_arg(&a, "700")); + assert!(out.get("api_key").is_none()); + assert!(out.get("gpu").is_none()); + assert_eq!(out["vision"]["cuda_device"], 0); + assert_eq!(out["env"]["STRATA_PLE_BATCH"], "0"); + assert!(build_config(&json!({}), &Cfg::new(), "", "ram").is_err()); +} + +#[test] +fn cartes_cuda() { + for (main, helper, want) in [ + ("1", "0", "1,0"), + ("0", "-1", "0"), + ("0", "", "0"), + ("", "", ""), + ("-1", "0", ""), + ] { + assert_eq!( + cuda_devices(&cfg(&[ + ("STRATA_MAIN_GPU", main), + ("STRATA_HELPER_GPU", helper) + ])), + want + ); + } +} + +fn machine() -> Env { + Env { + supported: true, + main: 1, + helper: 0, + ram_gb: 47.0, + avail_gb: 47.0, + disk_free_gb: 400.0, + gpus: vec![ + Gpu { + index: 0, + name: String::new(), + vram_gb: 8.0, + arch: 86, + }, + Gpu { + index: 1, + name: String::new(), + vram_gb: 16.0, + arch: 120, + }, + ], + ..Env::default() + } +} + +#[test] +fn recommandation() { + let d = tempfile::tempdir().unwrap(); + let p = Paths { + home: d.path().to_path_buf(), + }; + let mut env = machine(); + assert_eq!(recommend(&p, "swift", &env), "IQ3_XXS"); + assert_eq!(recommend(&p, "qwen", &env), "IQ3_XXS"); + assert_eq!(recommend(&p, "autre", &env), ""); + let f = fit_for(quant("IQ3_XXS").unwrap(), &env, 0.0); + assert!(f.ok && f.mmap && !f.drop); + env.ram_gb = 64.0; + env.avail_gb = 64.0; + assert_eq!(recommend(&p, "qwen", &env), "IQ3_S"); + let small = Env { + supported: true, + main: 0, + helper: -1, + ram_gb: 16.0, + disk_free_gb: 400.0, + gpus: vec![Gpu { + index: 0, + name: String::new(), + vram_gb: 8.0, + arch: 86, + }], + ..Env::default() + }; + assert_eq!(recommend(&p, "swift", &small), ""); + env.disk_free_gb = 50.0; + assert!(!fit_for(quant("Q2_0").unwrap(), &env, 0.0).ok); +} + +#[test] +fn noms() { + assert_eq!( + preset_name("swift", "IQ3_XXS"), + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS" + ); + assert_eq!( + preset_name("qwen", "Q2_0"), + "STRATA FLASH NEXT CLASSIQUE Q2_0" + ); + assert_eq!(family_label("qwen"), "Qwen3.8 Flash Next"); + assert_eq!(family_label("swift"), "Qwen3.8 Flash Next Swift 1.5"); + assert_eq!(family_label("x"), "x"); + assert_eq!(config_tag("/a/strata-swift-iq3_xxs.json"), "swift-iq3_xxs"); + assert_eq!(config_tag("autre.json"), "autre"); +} + +#[test] +fn donnees_deja_la() { + let mut env = machine(); + env.avail_gb = 0.0; + env.disk_free_gb = 32.0; + assert!(fit_for(quant("IQ3_XXS").unwrap(), &env, 120.0).ok); + assert!(!fit_for(quant("IQ3_XXS").unwrap(), &env, 0.0).ok); +} + +#[test] +fn reglages_du_preset() { + let base = json!({ "args": ["--kv", "int8", "--spec", "4"] }); + let out = build_config( + &base, + &cfg(&[("STRATA_KV", "fp16"), ("STRATA_SPEC", "3")]), + "", + "ram", + ) + .unwrap(); + let a = args_of(&out); + assert_eq!(arg_after(&a, "--kv"), "fp16"); + assert_eq!(arg_after(&a, "--spec"), "3"); +} + +#[test] +fn deja_sur_le_disque() { + let d = tempfile::tempdir().unwrap(); + let p = Paths { + home: d.path().to_path_buf(), + }; + let write = |rel: &str, n: usize| { + let f = p.data_dir().join(rel); + std::fs::create_dir_all(f.parent().unwrap()).unwrap(); + std::fs::write(f, vec![0u8; n]).unwrap(); + }; + write("models/swift-IQ3_XXS/a.gguf", 3000); + write("packs/swift-iq3_xxs/experts.bin", 2000); + write("mtp/rt/x", 500); + write("models/IQ2_XS/b.gguf", 7000); + assert_eq!((have_gb(&p, "swift", "IQ3_XXS") * 1e9).round(), 5500.0); + assert_eq!((have_gb(&p, "swift", "IQ2_XS") * 1e9).round(), 500.0); +} + +#[test] +fn reglages() { + let input = + "# NAME=x\nENGINE=strata\nCTX=131072\nSTRATA_KV=fp16\nSTRATA_SPEC=3\nSTRATA_HELPER_GPU=0\n"; + let r = SettingsReq { + ctx: 65536, + kv: "int8".into(), + spec: 4, + ..SettingsReq::default() + }; + let out = apply_settings(input, &r).unwrap(); + let c = crate::presets::parse_env(&out); + for (k, v) in [ + ("CTX", "65536"), + ("STRATA_KV", "int8"), + ("STRATA_SPEC", "4"), + ("STRATA_VISION", "0"), + ("STRATA_HELPER", "0"), + ("STRATA_HELPER_GPU", "0"), + ("ENGINE", "strata"), + ] { + assert_eq!(c.get(k).map(String::as_str), Some(v), "{k} : {out:?}"); + } + assert_eq!(out.matches("CTX=").count(), 1); + // Les bornes acceptées. + for (ctx, spec) in [(32768, 2), (MAX_CTX, 4)] { + let ok = SettingsReq { + ctx, + kv: "fp16".into(), + spec, + ..SettingsReq::default() + }; + assert!(apply_settings(input, &ok).is_ok(), "{ctx} {spec}"); + } + assert!(!helper_on(&c)); + assert_eq!( + cuda_devices(&cfg(&[ + ("STRATA_MAIN_GPU", "1"), + ("STRATA_HELPER_GPU", "0"), + ("STRATA_HELPER", "0") + ])), + "1" + ); + let base = json!({ "args": ["--vision", "--pack", "/p"], "vision": { "exe": "v" } }); + let b = build_config(&base, &c, "", "ram").unwrap(); + let a = args_of(&b); + assert!(!has_arg(&a, "--vision") && b.get("vision").is_none()); + assert!(!has_arg(&a, "--expert-cache-device1")); + for (ctx, kv, spec, why) in [ + (1000, "fp16", 3, "contexte hors limites : 1000"), + (32768, "q2", 3, "cache KV inconnu : q2"), + (32768, "fp16", 9, "MTP hors limites : 9"), + (36864 + 1, "fp16", 3, "contexte hors limites : 36865"), + (MAX_CTX + 4096, "fp16", 3, "contexte hors limites : 266240"), + (32768, "fp16", 1, "MTP hors limites : 1"), + (32768, "fp16", 5, "MTP hors limites : 5"), + (28672, "fp16", 3, "contexte hors limites : 28672"), + ] { + let bad = SettingsReq { + ctx, + kv: kv.into(), + spec, + ..SettingsReq::default() + }; + assert_eq!(apply_settings(input, &bad).unwrap_err(), why); + } +} + +#[test] +fn moteur_du_preset() { + for (v, want) in [ + ("", ENGINE_LLAMACPP), + ("llamacpp", ENGINE_LLAMACPP), + ("strata", ENGINE_STRATA), + (" Strata ", ENGINE_STRATA), + ("moe", ENGINE_STRATA), + ("autre", ENGINE_LLAMACPP), + ] { + assert_eq!(engine_of(&cfg(&[("ENGINE", v)])), want, "{v:?}"); + } +} + +#[test] +fn placement_des_experts() { + let d = tempfile::tempdir().unwrap(); + let p = Paths { + home: d.path().to_path_buf(), + }; + let pack = d.path().join("pack"); + std::fs::create_dir_all(&pack).unwrap(); + let args = vec!["--pack".to_string(), pack.to_string_lossy().into_owned()]; + let mut c = cfg(&[ + ("STRATA_CONFIG", "/x/strata-swift-iq3_xxs.json"), + ("STRATA_HELPER_GPU", "1"), + ("STRATA_DROP", "1"), + ]); + for (experts, avail, want) in [ + ("", 44.0, "disk"), + ("", 60.0, "ram"), + ("auto", 52.8, "disk"), + ("disk", 60.0, "disk"), + ("ram", 20.0, "ram"), + ] { + c.insert("STRATA_EXPERTS".into(), experts.into()); + assert_eq!( + resolve_experts(&p, &c, &args, avail, 12.0), + want, + "{experts} {avail}" + ); + } + std::fs::write(pack.join("experts.bin"), "x").unwrap(); + std::fs::create_dir_all(p.src_dir().join("engine-cuda12")).unwrap(); + std::fs::write(p.engine_marker(), format!("{ENGINE_ASSET}\n")).unwrap(); + c.insert("STRATA_EXPERTS".into(), String::new()); + assert_eq!(resolve_experts(&p, &c, &args, 44.0, 12.0), "drop"); + assert_eq!(resolve_experts(&p, &c, &args, 30.0, 12.0), "arena"); + c.insert("STRATA_HELPER".into(), "0".into()); + assert_eq!(resolve_experts(&p, &c, &args, 44.0, 12.0), "arena"); + c.insert("STRATA_EXPERTS".into(), "disk".into()); + assert_eq!(resolve_experts(&p, &c, &args, 60.0, 12.0), "arena"); + assert_eq!( + resolve_experts( + &p, + &cfg(&[("STRATA_CONFIG", "/x/autre.json")]), + &[], + 500.0, + 0.0 + ), + "disk" + ); +} + +#[test] +fn modes_des_experts() { + let base = json!({ + "args": ["--pack", "/p", "--resident-experts", "--pcie-frac", "0.3"], + "env": { "X": "1" }, + }); + let c = cfg(&[("STRATA_HELPER_GPU", "1")]); + let out = build_config(&base, &c, "", "disk").unwrap(); + let a = args_of(&out); + assert!(has_arg(&a, "--mmap-experts") && !has_arg(&a, "--resident-experts")); + assert_eq!(arg_after(&a, "--pcie-frac"), "0"); + assert!(out["env"].get("STRATA_ARENA_MMAP").is_none()); + assert_eq!(out["env"]["X"], "1"); + let out = build_config(&base, &c, "", "ram").unwrap(); + let a = args_of(&out); + assert!(!has_arg(&a, "--mmap-experts") && !has_arg(&a, "--resident-experts")); + assert!(out["env"].get("STRATA_REMOTE_DROP").is_none()); + let out = build_config(&base, &c, "", "arena").unwrap(); + assert_eq!(arg_after(&args_of(&out), "--pcie-frac"), "0"); + assert_eq!(out["env"]["STRATA_ARENA_MMAP"], "1"); + let out = build_config(&base, &c, "", "drop").unwrap(); + assert!(!has_arg(&args_of(&out), "--pcie-frac")); + assert_eq!(out["env"]["STRATA_REMOTE_DROP"], "1"); + assert_eq!(out["env"]["STRATA_STAGER_THREADS"], "8"); + let out = build_config(&base, &cfg(&[("STRATA_HELPER_GPU", "-1")]), "", "drop").unwrap(); + assert!(out["env"].get("STRATA_REMOTE_DROP").is_none()); +} + +#[test] +fn reglages_des_experts() { + let input = "ENGINE=strata\nSTRATA_EXPERTS=auto\n"; + let mut r = SettingsReq { + ctx: 131072, + kv: "fp16".into(), + spec: 3, + experts: "disk".into(), + ..SettingsReq::default() + }; + let out = apply_settings(input, &r).unwrap(); + assert_eq!(crate::presets::parse_env(&out)["STRATA_EXPERTS"], "disk"); + r.experts = "nvme".into(); + assert_eq!( + apply_settings(input, &r).unwrap_err(), + "placement des experts inconnu : nvme" + ); + r.experts = String::new(); + let out = apply_settings(input, &r).unwrap(); + assert_eq!(crate::presets::parse_env(&out)["STRATA_EXPERTS"], "auto"); +} + +#[test] +fn nombres_a_la_go() { + assert_eq!(go_g(8192.0), "8192"); + assert_eq!(go_g(123456.0), "123456"); + assert_eq!(go_g(1e6), "1e+06"); + assert_eq!(go_g(1234567.0), "1.234567e+06"); + assert_eq!(go_g(0.3), "0.3"); + assert_eq!(go_g(0.0001), "0.0001"); + assert_eq!(go_g(0.00001), "1e-05"); + assert_eq!(go_g(-2.5), "-2.5"); + assert_eq!(go_sprint(&json!("x")), "x"); + assert_eq!(go_sprint(&json!(true)), "true"); + assert_eq!(go_num(34.0), json!(34)); + assert_eq!(go_num(35.5), json!(35.5)); +} + +#[test] +fn ligne_par_ligne() { + let mut s = api::SinkWriter::default(); + assert_eq!(s.write(b"a\nb"), vec!["a"]); + assert_eq!(s.write(b"c\r"), Vec::::new()); + assert_eq!(s.write(b"\n10%\r20%\r"), vec!["bc", "10%"]); + assert_eq!(s.write(b"fin\r\n"), vec!["fin"]); +} + +/// La RAM du moteur Strata en marche : l'arbre du service, lu dans /proc. +#[test] +fn ram_du_moteur_en_marche() { + let home = tempfile::tempdir().unwrap(); + let root = tempfile::tempdir().unwrap(); + let probe = crate::backends::probe::Probe { + path: Some(vec![]), + root: root.path().to_path_buf(), + }; + let st = api::Strata::new(home.path().to_path_buf(), probe); + let status = |pid: &str, ppid: i64, kb: i64| { + let d = root.path().join("proc").join(pid); + std::fs::create_dir_all(&d).unwrap(); + std::fs::write( + d.join("status"), + format!("Name:\tx\nPPid:\t{ppid}\nVmRSS:\t {kb} kB\n"), + ) + .unwrap(); + }; + status("100", 1, 1_048_576); + status("101", 100, 2048); + status("102", 101, 1024); + status("200", 1, 999_999); + std::fs::create_dir_all(root.path().join("proc/self")).unwrap(); + let strata = cfg(&[("ENGINE", "strata")]); + assert_eq!(st.engine_rss_gb(&strata), 0.0, "sans fichier de PID"); + std::fs::write(home.path().join("loki-engine.pid"), "100\n").unwrap(); + let want = (1_048_576.0 + 2048.0 + 1024.0) * 1024.0 / 1e9; + assert!((st.engine_rss_gb(&strata) - want).abs() < 1e-9); + assert_eq!(st.engine_rss_gb(&Cfg::new()), 0.0, "llama.cpp actif"); + std::fs::write( + root.path().join("proc/meminfo"), + "MemTotal: 8388608 kB\nMemAvailable: 4194304 kB\n", + ) + .unwrap(); + assert_eq!(st.total_ram_gb(), 8.0); + assert!((st.mem_available_gb() - 4194304.0 * 1024.0 / 1e9).abs() < 1e-9); +} + +/// Les drapeaux posés une seule fois, où qu'ils soient dans la liste. +#[test] +fn drapeaux_uniques() { + let v = |a: &[&str]| a.iter().map(|s| s.to_string()).collect::>(); + assert_eq!( + set_arg(v(&["--a", "1", "--kv", "int8"]), "--kv", "fp16"), + v(&["--a", "1", "--kv", "fp16"]) + ); + assert_eq!( + set_arg(v(&["--kv"]), "--kv", "x"), + v(&["--kv", "--kv", "x"]) + ); + assert_eq!( + drop_flag_value(v(&["--a", "1", "--b", "2"]), "--b"), + v(&["--a", "1"]) + ); + assert_eq!(drop_flag(v(&["--a", "--b", "--a"]), "--a"), v(&["--b"])); + let base = json!({ "args": ["--remote-expert-opt", "--pack", "/p"] }); + let out = build_config(&base, &cfg(&[("STRATA_HELPER_GPU", "1")]), "", "drop").unwrap(); + let a = args_of(&out); + assert_eq!( + a.iter().filter(|x| *x == "--remote-expert-opt").count(), + 1, + "{a:?}" + ); + assert_eq!(out["env"]["STRATA_STAGER_RING"], "32"); + assert_eq!(out["env"]["STRATA_NO_LARGEPAGES"], "1"); +} diff --git a/rust/loki-rs/tests/common/fakego.rs b/rust/loki-rs/tests/common/fakego.rs index 1385d0c..5b7a92f 100644 --- a/rust/loki-rs/tests/common/fakego.rs +++ b/rust/loki-rs/tests/common/fakego.rs @@ -661,6 +661,7 @@ pub struct Opts { pub update: bool, pub backends: Option>, pub engineimg: Option>, + pub strata: Option>, } /// Comme [`start`], avec la conversation tenue par la façade @@ -764,6 +765,7 @@ pub async fn start_with( update: opts.update, backends: opts.backends, engineimg: opts.engineimg, + strata: opts.strata, }; tokio::spawn(loki_rs::proxy::serve(fl, cfg, async move { let _ = rx.await; diff --git a/rust/loki-rs/tests/lot2.rs b/rust/loki-rs/tests/lot2.rs index 7c9d6c6..d3fc44f 100644 --- a/rust/loki-rs/tests/lot2.rs +++ b/rust/loki-rs/tests/lot2.rs @@ -108,6 +108,7 @@ async fn banc(cle: Option<&str>) -> Banc { update: false, backends: None, engineimg: None, + strata: None, }; tokio::spawn(loki_rs::proxy::serve(l, cfg, async move { let _ = rx.await; diff --git a/rust/loki-rs/tests/parity_strata/strata.json b/rust/loki-rs/tests/parity_strata/strata.json new file mode 100644 index 0000000..3117389 --- /dev/null +++ b/rust/loki-rs/tests/parity_strata/strata.json @@ -0,0 +1,5708 @@ +{ + "machines": { + "aide-ancienne": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce GTX 1070, 8192, 0, 6.1, 00000000:01:00.0, 3, 3, 16, 16, 4004\\n1, NVIDIA GeForce RTX 4090, 24564, 0, 8.9, 00000000:02:00.0, 4, 4, 16, 16, 10501\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + }, + "deux-cartes": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 3070, 8192, 100, 8.6, 00000000:01:00.0, 4, 4, 16, 16, 7001\\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 5, 12.0, 00000000:02:00.0, 5, 5, 16, 16, 14001\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + }, + "jumelles": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 4060 Ti, 16311, 0, 8.9, 00000000:01:00.0, 4, 4, 8, 8, 9001\\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 0, 12.0, 00000000:02:00.0, 5, 5, 8, 8, 14001\\n2, NVIDIA GeForce GTX 1650, 4096, 0, 7.46, 00000000:03:00.0, 3, 3, 16, 16, 4001\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + }, + "petite-carte": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 3050, 6144, 0, 8.6, 00000000:01:00.0, 4, 4, 8, 8, 7001\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + }, + "python-ancien": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 3070, 8192, 100, 8.6, 00000000:01:00.0, 4, 4, 16, 16, 7001\\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 5, 12.0, 00000000:02:00.0, 5, 5, 16, 16, 14001\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.8.10';;\n-c) exit 0;;\nesac\n" + }, + "python-casse": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 3070, 8192, 100, 8.6, 00000000:01:00.0, 4, 4, 16, 16, 7001\\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 5, 12.0, 00000000:02:00.0, 5, 5, 16, 16, 14001\\n';;\nesac\n", + "python3": "#!/bin/sh\nexit 1\n" + }, + "python-muet": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 3070, 8192, 100, 8.6, 00000000:01:00.0, 4, 4, 16, 16, 7001\\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 5, 12.0, 00000000:02:00.0, 5, 5, 16, 16, 14001\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python inconnu';;\n-c) exit 0;;\nesac\n" + }, + "sans-carte": { + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + }, + "sans-python": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 3070, 8192, 100, 8.6, 00000000:01:00.0, 4, 4, 16, 16, 7001\\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 5, 12.0, 00000000:02:00.0, 5, 5, 16, 16, 14001\\n';;\nesac\n" + }, + "sans-venv": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce RTX 3070, 8192, 100, 8.6, 00000000:01:00.0, 4, 4, 16, 16, 7001\\n1, NVIDIA GeForce RTX 5060 Ti, 16311, 5, 12.0, 00000000:02:00.0, 5, 5, 16, 16, 14001\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.11.2';;\n-c) echo 'ModuleNotFoundError: No module named ensurepip'; exit 1;;\nesac\n" + }, + "smi-en-panne": { + "nvidia-smi": "#!/bin/sh\nexit 9\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + }, + "smi-vide": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + }, + "vieille-carte": { + "nvidia-smi": "#!/bin/sh\ncase \"$1\" in\n--query-gpu=*) printf '0, NVIDIA GeForce GTX 1080 Ti, 11264, 0, 6.1, 00000000:01:00.0, 3, 3, 16, 16, 5505\\n';;\nesac\n", + "python3": "#!/bin/sh\ncase \"$1\" in\n--version) echo 'Python 3.12.3';;\n-c) exit 0;;\nesac\n" + } + }, + "setup": "#!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "steps": [ + { + "name": "aucune carte", + "machine": "sans-carte", + "meminfo": "MemTotal: 49283072 kB\nMemFree: 1000000 kB\nMemAvailable: 41943040 kB\n", + "disk_free": 400000000000, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": null, + "helper": -1, + "main": -1, + "ram_gb": 47, + "reason": "Strata demande une carte NVIDIA (nvidia-smi introuvable — sélection GPU disponible uniquement sur NVIDIA)", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~62" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "Q2_0" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "nvidia-smi en panne", + "machine": "smi-en-panne", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": null, + "helper": -1, + "main": -1, + "ram_gb": 47, + "reason": "Strata demande une carte NVIDIA (nvidia-smi a échoué: exit status 9)", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~62" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "Q2_0" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "nvidia-smi sans carte", + "machine": "smi-vide", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": null, + "helper": -1, + "main": -1, + "ram_gb": 47, + "reason": "Strata demande une carte NVIDIA (aucun GPU NVIDIA détecté)", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~62" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "Q2_0" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "carte trop ancienne", + "machine": "vieille-carte", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 61, + "index": 0, + "name": "NVIDIA GeForce GTX 1080 Ti", + "vram_gb": 11 + } + ], + "helper": -1, + "main": -1, + "ram_gb": 47, + "reason": "la carte NVIDIA GeForce GTX 1080 Ti est trop ancienne pour Strata (RTX 20 ou plus récente)", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~62" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "Q2_0" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "carte trop petite", + "machine": "petite-carte", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3050", + "vram_gb": 6 + } + ], + "helper": -1, + "main": -1, + "ram_gb": 47, + "reason": "la carte NVIDIA GeForce RTX 3050 n'a que 6 Go de VRAM (8 Go minimum)", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~55" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "demande plus de mémoire : 47 Go de RAM + VRAM, il en faut ~62" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "Q2_0" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "sans Python", + "machine": "sans-python", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "ram_gb": 47, + "reason": "Python 3 est introuvable : installe-le (apt install python3 python3-venv)", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "Python en panne", + "machine": "python-casse", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "ram_gb": 47, + "reason": "Python 3 est introuvable : installe-le (apt install python3 python3-venv)", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "Python illisible", + "machine": "python-muet", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "ram_gb": 47, + "reason": "version de Python illisible : Python inconnu", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "Python trop ancien", + "machine": "python-ancien", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.8", + "ram_gb": 47, + "reason": "Python 3.8 est trop ancien : il faut Python 3.10 ou plus récent", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "sans venv", + "machine": "sans-venv", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.11", + "ram_gb": 47, + "reason": "le module venv de Python manque : apt install python3.11-venv", + "supported": false + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "deux cartes, 47 Go", + "machine": "deux-cartes", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "trois cartes, la plus récente devant", + "machine": "jumelles", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 89, + "index": 0, + "name": "NVIDIA GeForce RTX 4060 Ti", + "vram_gb": 15.9287109375 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + }, + { + "arch": 75, + "index": 2, + "name": "NVIDIA GeForce GTX 1650", + "vram_gb": 4 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "carte d'aide trop ancienne", + "machine": "aide-ancienne", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 61, + "index": 0, + "name": "NVIDIA GeForce GTX 1070", + "vram_gb": 8 + }, + { + "arch": 89, + "index": 1, + "name": "NVIDIA GeForce RTX 4090", + "vram_gb": 23.98828125 + } + ], + "helper": -1, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "64 Go de RAM", + "machine": "deux-cartes", + "meminfo": "MemTotal: 67108864 kB\nMemAvailable: 65011712 kB\n", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 64, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 64, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_S" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "16 Go de RAM", + "meminfo": "MemTotal: 16777216 kB\nMemAvailable: 12582912 kB\n", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 12.884901888, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 16, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~55" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + }, + "why": "demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~46" + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~48" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~55" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~62" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "disque presque plein", + "meminfo": "MemTotal: 49283072 kB\nMemFree: 1000000 kB\nMemAvailable: 41943040 kB\n", + "disk_free": 50000000000, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 50, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "pas assez d'espace disque : 50 Go libres, il en faut ~73" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "pas assez d'espace disque : 50 Go libres, il en faut ~81" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + }, + "why": "pas assez d'espace disque : 50 Go libres, il en faut ~71" + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "pas assez d'espace disque : 50 Go libres, il en faut ~73" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "pas assez d'espace disque : 50 Go libres, il en faut ~81" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "pas assez d'espace disque : 50 Go libres, il en faut ~89" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "disque juste trop petit", + "disk_free": 78000000000, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 78, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "pas assez d'espace disque : 78 Go libres, il en faut ~81" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ2_XS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "pas assez d'espace disque : 78 Go libres, il en faut ~81" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "pas assez d'espace disque : 78 Go libres, il en faut ~89" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ2_XS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets" + ] + }, + { + "name": "données déjà là", + "disk_free": 60000000000, + "files": { + "strata/data/models/swift-IQ3_XXS/a.gguf": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 60, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "pas assez d'espace disque : 60 Go libres, il en faut ~73" + }, + { + "disk_gb": 75.799998, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "pas assez d'espace disque : 60 Go libres, il en faut ~81" + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + }, + "why": "pas assez d'espace disque : 60 Go libres, il en faut ~71" + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + }, + "why": "pas assez d'espace disque : 60 Go libres, il en faut ~73" + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + }, + "why": "pas assez d'espace disque : 60 Go libres, il en faut ~81" + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": false, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + }, + "why": "pas assez d'espace disque : 60 Go libres, il en faut ~89" + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "meminfo sans MemAvailable", + "meminfo": "MemTotal: 49283072 kB\n", + "disk_free": 400000000000, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": false, + "env": { + "avail_gb": 47, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.799998, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": false, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [], + "version": "1.0" + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages en GET", + "meminfo": "MemTotal: 49283072 kB\nMemFree: 1000000 kB\nMemAvailable: 41943040 kB\n", + "method": "GET", + "path": "/api/strata/settings", + "status": 405, + "out": { + "error": "POST attendu", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages illisibles", + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"ctx\":\"x\"}", + "status": 400, + "out": { + "error": "json: cannot unmarshal string into Go struct field strataSettingsReq.ctx of type int", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages sans preset", + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"\",\"ctx\":65536,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true}", + "status": 400, + "out": { + "error": "preset invalide", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages, preset avec chemin", + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"../x\",\"ctx\":65536,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true}", + "status": 400, + "out": { + "error": "preset invalide", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages, preset absent", + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"absent\",\"ctx\":65536,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true}", + "status": 404, + "out": { + "error": "modèle introuvable", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages, preset llama.cpp", + "files": { + "presets/llama.env": "MODEL=/m.gguf\n" + }, + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"llama\",\"ctx\":65536,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true}", + "status": 404, + "out": { + "error": "modèle introuvable", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages hors limites", + "files": { + "presets/S.env": "# NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nCTX=131072\n" + }, + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"S\",\"ctx\":1000,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true}", + "status": 400, + "out": { + "error": "contexte hors limites : 1000", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nCTX=131072\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages, experts inconnus", + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"S\",\"ctx\":65536,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true,\"experts\":\"nvme\"}", + "status": 400, + "out": { + "error": "placement des experts inconnu : nvme", + "ok": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nCTX=131072\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages d'un preset inactif", + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"S\",\"ctx\":65536,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true,\"experts\":\"disk\"}", + "status": 200, + "out": { + "ok": true, + "restarted": false + }, + "actions": [], + "after": {}, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nCTX=65536\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\nSTRATA_EXPERTS=disk\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages du preset actif", + "config": { + "CTX": "65536", + "ENGINE": "strata", + "STRATA_EXPERTS": "disk", + "STRATA_HELPER": "1", + "STRATA_HELPER_GPU": "0", + "STRATA_KV": "int8", + "STRATA_SPEC": "4", + "STRATA_VISION": "0" + }, + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"S\",\"ctx\":98304,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true}", + "status": 200, + "out": { + "ok": true, + "restarted": true + }, + "actions": [ + "restart" + ], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "réglages du preset actif pendant une optimisation", + "tune": true, + "method": "POST", + "path": "/api/strata/settings", + "body": "{\"preset\":\"S\",\"ctx\":98304,\"kv\":\"int8\",\"spec\":4,\"vision\":false,\"helper\":true}", + "status": 409, + "out": { + "error": "optimisation en cours (loki tune) : le moteur est réservé aux essais — attends la fin ou annule-la", + "ok": false, + "tuning": true + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "installation en GET", + "method": "GET", + "path": "/api/strata/install", + "status": 405, + "out": { + "error": "POST attendu", + "ok": false + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "installation illisible", + "method": "POST", + "path": "/api/strata/install", + "body": "[", + "status": 400, + "out": { + "error": "unexpected EOF", + "ok": false + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "installation d'un quant inconnu", + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"swift\",\"quant\":\"Q2_0\"}", + "status": 400, + "out": { + "error": "version ou quant inconnu", + "ok": false + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "installation pendant une optimisation", + "tune": true, + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"swift\",\"quant\":\"IQ3_XXS\"}", + "status": 409, + "out": { + "error": "optimisation en cours (loki tune) : le moteur est réservé aux essais — attends la fin ou annule-la", + "ok": false + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "installation sur une machine sans carte", + "machine": "sans-carte", + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"swift\",\"quant\":\"IQ3_XXS\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "Strata demande une carte NVIDIA (nvidia-smi introuvable — sélection GPU disponible uniquement sur NVIDIA)", + "exists": true, + "lines": [ + "✗ Strata demande une carte NVIDIA (nvidia-smi introuvable — sélection GPU disponible uniquement sur NVIDIA)" + ], + "new": "", + "next": 1, + "old": "", + "phase": "échec", + "running": false, + "started_at": "{{T}}" + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "installation qui ne tient pas", + "machine": "deux-cartes", + "meminfo": "MemTotal: 16777216 kB\nMemAvailable: 12582912 kB\n", + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"qwen\",\"quant\":\"IQ3_S\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "IQ3_S ne tient pas sur cette machine : demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~62", + "exists": true, + "lines": [ + "✗ IQ3_S ne tient pas sur cette machine : demande plus de mémoire : 40 Go de RAM + VRAM, il en faut ~62" + ], + "new": "", + "next": 1, + "old": "", + "phase": "échec", + "running": false, + "started_at": "{{T}}" + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "release introuvable", + "meminfo": "MemTotal: 49283072 kB\nMemFree: 1000000 kB\nMemAvailable: 41943040 kB\n", + "release": { + "status": 404, + "src": [ + { + "name": "ajean-moe-1.0/", + "type": "dir", + "mode": 493 + }, + { + "name": "ajean-moe-1.0/setup.sh", + "type": "file", + "body": "#!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "mode": 493 + }, + { + "name": "ajean-moe-1.0/setup.py", + "type": "file", + "body": "# installeur\n", + "mode": 420 + }, + { + "name": "ajean-moe-1.0/serve/server.py", + "type": "file", + "body": "# serveur\n", + "mode": 420 + } + ], + "engine": "x" + }, + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"swift\",\"quant\":\"IQ3_XXS\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "téléchargement de ajean-moe-src-1.0.tar.gz : HTTP 404", + "exists": true, + "lines": [ + "▶ téléchargement de ajean-moe-src-1.0.tar.gz…", + "✗ téléchargement de ajean-moe-src-1.0.tar.gz : HTTP 404" + ], + "new": "", + "next": 2, + "old": "", + "phase": "échec", + "running": false, + "started_at": "{{T}}" + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/dl", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] + }, + { + "name": "moteur altéré", + "release": { + "src": [ + { + "name": "ajean-moe-1.0/", + "type": "dir", + "mode": 493 + }, + { + "name": "ajean-moe-1.0/setup.sh", + "type": "file", + "body": "#!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "mode": 493 + }, + { + "name": "ajean-moe-1.0/setup.py", + "type": "file", + "body": "# installeur\n", + "mode": 420 + }, + { + "name": "ajean-moe-1.0/serve/server.py", + "type": "file", + "body": "# serveur\n", + "mode": 420 + } + ], + "engine": "moteur strata 1.0", + "bad_sha": true + }, + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"swift\",\"quant\":\"IQ3_XXS\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "ajean-moe-engine-1.0-linux-x64-cuda12.zip : empreinte SHA-256 inattendue (fichier altéré ou incomplet)", + "exists": true, + "lines": [ + "▶ téléchargement de ajean-moe-src-1.0.tar.gz…", + "▶ téléchargement de ajean-moe-engine-1.0-linux-x64-cuda12.zip…", + "✗ ajean-moe-engine-1.0-linux-x64-cuda12.zip : empreinte SHA-256 inattendue (fichier altéré ou incomplet)" + ], + "new": "", + "next": 3, + "old": "", + "phase": "échec", + "running": false, + "started_at": "{{T}}" + }, + "actions": [], + "after": { + "config/CTX": "98304", + "config/ENGINE": "strata", + "config/STRATA_HELPER": "1", + "config/STRATA_KV": "int8" + }, + "tree": [ + "d presets", + "d strata", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/dl", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/dl/ajean-moe-src-1.0.tar.gz" + ] + }, + { + "name": "installation", + "release": { + "src": [ + { + "name": "ajean-moe-1.0/", + "type": "dir", + "mode": 493 + }, + { + "name": "ajean-moe-1.0/setup.sh", + "type": "file", + "body": "#!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "mode": 493 + }, + { + "name": "ajean-moe-1.0/setup.py", + "type": "file", + "body": "# installeur\n", + "mode": 420 + }, + { + "name": "ajean-moe-1.0/serve/server.py", + "type": "file", + "body": "# serveur\n", + "mode": 420 + } + ], + "engine": "moteur strata 1.0" + }, + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"swift\",\"quant\":\"IQ3_XXS\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "", + "exists": true, + "lines": [ + "ajean-moe-src-1.0.tar.gz déjà téléchargé", + "▶ téléchargement de ajean-moe-engine-1.0-linux-x64-cuda12.zip…", + "▶ décompression de Strata…", + "▶ installation de Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (téléchargement de ~76 Go)…", + "installeur : --setup --yes --no-start --no-browser --family swift --model IQ3_XXS --context 131072 --vision gpu --cuda 12 --prebuilt {{HOME}}/strata/prebuilt/ --data-dir {{HOME}}/strata/data --gpu 1 --low-ram off", + "cache : {{HOME}}/strata/cache", + "modèle 10%", + "modèle téléchargé", + "prêt : strata-swift-iq3_xxs.json", + "▶ activation du modèle (premier chargement : quelques minutes)…", + "✓ Qwen3.8 Flash Next Swift 1.5 IQ3_XXS installé (Strata)" + ], + "new": "", + "next": 11, + "old": "", + "phase": "Qwen3.8 Flash Next Swift 1.5 IQ3_XXS installé (Strata)", + "running": false, + "started_at": "{{T}}" + }, + "actions": [ + "restart" + ], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "après l'installation", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "active": true, + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "auto", + "has_helper": true, + "helper_gpu": "RTX 3070 (8 Go)", + "helper_on": true, + "kv": "fp16", + "kv_resident": "32768", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "disk", + "mode_label": "lus depuis le disque (mmap)", + "prefill": "16384", + "short_read": "150", + "spec": "3", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 3070 (8 Go)" + }, + "disk_gb": 75.799998, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "mode lancé connu, modèles inactifs", + "files": { + "presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env": "# NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env": "ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n" + }, + "state": { + "strata_experts_mode": "drop" + }, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "active": true, + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": true, + "experts": "auto", + "has_helper": true, + "helper_gpu": "RTX 3070 (8 Go)", + "helper_on": true, + "kv": "fp16", + "kv_resident": "32768", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": false, + "mode": "drop", + "mode_label": "verrouillés en RAM, hors ceux de la carte d'appoint", + "prefill": "16384", + "short_read": "150", + "spec": "3", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 3070 (8 Go)" + }, + "disk_gb": 75.799998, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "ram", + "has_helper": true, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 3070 (8 Go)", + "mmap": false, + "mode": "ram", + "mode_label": "chargés et verrouillés en RAM", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": false + }, + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "disk", + "has_helper": false, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "disk", + "mode_label": "lus depuis le disque (mmap)", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 5060 Ti (16 Go)" + }, + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "experts.bin et moteur du paquet", + "files": { + "strata/data/packs/swift-iq3_xxs/experts.bin": "x" + }, + "state": { + "strata_experts_mode": "" + }, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "active": true, + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "auto", + "has_helper": true, + "helper_gpu": "RTX 3070 (8 Go)", + "helper_on": true, + "kv": "fp16", + "kv_resident": "32768", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "arena", + "mode_label": "experts.bin mappé (cache système)", + "prefill": "16384", + "short_read": "150", + "spec": "3", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 3070 (8 Go)" + }, + "disk_gb": 75.799997999, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "ram", + "has_helper": true, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 3070 (8 Go)", + "mmap": false, + "mode": "ram", + "mode_label": "chargés et verrouillés en RAM", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": false + }, + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "disk", + "has_helper": false, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "arena", + "mode_label": "experts.bin mappé (cache système)", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 5060 Ti (16 Go)" + }, + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "RAM juste sous le seuil du mode hors RAM", + "meminfo": "MemTotal: 49283072 kB\nMemAvailable: 43164063 kB\n", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 44.200000512, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "active": true, + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "auto", + "has_helper": true, + "helper_gpu": "RTX 3070 (8 Go)", + "helper_on": true, + "kv": "fp16", + "kv_resident": "32768", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "arena", + "mode_label": "experts.bin mappé (cache système)", + "prefill": "16384", + "short_read": "150", + "spec": "3", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 3070 (8 Go)" + }, + "disk_gb": 75.799997999, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "ram", + "has_helper": true, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 3070 (8 Go)", + "mmap": false, + "mode": "ram", + "mode_label": "chargés et verrouillés en RAM", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": false + }, + "disk_gb": 66.4, + "drop": false, + "mmap": false, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "disk", + "has_helper": false, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "arena", + "mode_label": "experts.bin mappé (cache système)", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 5060 Ti (16 Go)" + }, + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "RAM au-dessus du seuil du mode hors RAM", + "meminfo": "MemTotal: 49283072 kB\nMemAvailable: 43457032 kB\n", + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 44.500000768, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "active": true, + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": true, + "experts": "auto", + "has_helper": true, + "helper_gpu": "RTX 3070 (8 Go)", + "helper_on": true, + "kv": "fp16", + "kv_resident": "32768", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": false, + "mode": "drop", + "mode_label": "verrouillés en RAM, hors ceux de la carte d'appoint", + "prefill": "16384", + "short_read": "150", + "spec": "3", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 3070 (8 Go)" + }, + "disk_gb": 75.799997999, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "ram", + "has_helper": true, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 3070 (8 Go)", + "mmap": false, + "mode": "ram", + "mode_label": "chargés et verrouillés en RAM", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": false + }, + "disk_gb": 66.4, + "drop": false, + "mmap": false, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "disk", + "has_helper": false, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "arena", + "mode_label": "experts.bin mappé (cache système)", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 5060 Ti (16 Go)" + }, + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "mode hors RAM coupé dans le preset", + "files": { + "presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env": "# NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=0\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n" + }, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 44.500000768, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "auto", + "has_helper": true, + "helper_gpu": "RTX 3070 (8 Go)", + "helper_on": true, + "kv": "fp16", + "kv_resident": "32768", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "arena", + "mode_label": "experts.bin mappé (cache système)", + "prefill": "16384", + "short_read": "150", + "spec": "3", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 3070 (8 Go)" + }, + "disk_gb": 75.799997999, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "ram", + "has_helper": true, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 3070 (8 Go)", + "mmap": false, + "mode": "ram", + "mode_label": "chargés et verrouillés en RAM", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": false + }, + "disk_gb": 66.4, + "drop": false, + "mmap": false, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "disk", + "has_helper": false, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "arena", + "mode_label": "experts.bin mappé (cache système)", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 5060 Ti (16 Go)" + }, + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=0\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "moteur d'un autre paquet", + "meminfo": "MemTotal: 49283072 kB\nMemFree: 1000000 kB\nMemAvailable: 41943040 kB\n", + "files": { + "strata/ajean-moe-1.0/engine-cuda12/.loki-engine": "ajean-moe-engine-0.9-linux-x64-cuda12.zip\n" + }, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "auto", + "has_helper": true, + "helper_gpu": "RTX 3070 (8 Go)", + "helper_on": true, + "kv": "fp16", + "kv_resident": "32768", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "disk", + "mode_label": "lus depuis le disque (mmap)", + "prefill": "16384", + "short_read": "150", + "spec": "3", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 3070 (8 Go)" + }, + "disk_gb": 75.799997999, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "ram", + "has_helper": true, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 3070 (8 Go)", + "mmap": false, + "mode": "ram", + "mode_label": "chargés et verrouillés en RAM", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": false + }, + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "details": { + "cache_root": "256", + "ctx": "131072", + "drop": false, + "experts": "disk", + "has_helper": false, + "helper_on": false, + "kv": "int8", + "main_gpu": "RTX 5060 Ti (16 Go)", + "mmap": true, + "mode": "disk", + "mode_label": "lus depuis le disque (mmap)", + "prefill": "16384", + "short_read": "150", + "spec": "4", + "version": "1.0", + "vision": true, + "vision_gpu": "RTX 5060 Ti (16 Go)" + }, + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=0\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-0.9-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "réinstallation, moteur téléchargé périmé", + "files": { + "strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip": "ancien moteur" + }, + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"swift\",\"quant\":\"IQ3_XXS\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "", + "exists": true, + "lines": [ + "ajean-moe-src-1.0.tar.gz déjà téléchargé", + "▶ téléchargement de ajean-moe-engine-1.0-linux-x64-cuda12.zip…", + "▶ installation de Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (téléchargement de ~76 Go)…", + "installeur : --setup --yes --no-start --no-browser --family swift --model IQ3_XXS --context 131072 --vision gpu --cuda 12 --prebuilt {{HOME}}/strata/prebuilt/ --data-dir {{HOME}}/strata/data --gpu 1 --low-ram off", + "cache : {{HOME}}/strata/cache", + "modèle 10%", + "modèle téléchargé", + "prêt : strata-swift-iq3_xxs.json", + "▶ activation du modèle (premier chargement : quelques minutes)…", + "✓ Qwen3.8 Flash Next Swift 1.5 IQ3_XXS installé (Strata)" + ], + "new": "", + "next": 10, + "old": "", + "phase": "Qwen3.8 Flash Next Swift 1.5 IQ3_XXS installé (Strata)", + "running": false, + "started_at": "{{T}}" + }, + "actions": [ + "restart" + ], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "installeur en échec", + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"qwen\",\"quant\":\"Q2_0\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "l'installation a échoué : exit status 3 (voir le journal)", + "exists": true, + "lines": [ + "ajean-moe-src-1.0.tar.gz déjà téléchargé", + "ajean-moe-engine-1.0-linux-x64-cuda12.zip déjà téléchargé", + "▶ installation de Qwen3.8 Flash Next Q2_0 (téléchargement de ~66 Go)…", + "installeur : --setup --yes --no-start --no-browser --family qwen --model Q2_0 --context 131072 --vision gpu --cuda 12 --prebuilt {{HOME}}/strata/prebuilt/ --data-dir {{HOME}}/strata/data --gpu 1 --low-ram off", + "cache : {{HOME}}/strata/cache", + "modèle 10%", + "modèle téléchargé", + "erreur : téléchargement interrompu", + "✗ l'installation a échoué : exit status 3 (voir le journal)" + ], + "new": "", + "next": 9, + "old": "", + "phase": "échec", + "running": false, + "started_at": "{{T}}" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "installeur sans configuration", + "method": "POST", + "path": "/api/strata/install", + "body": "{\"family\":\"qwen\",\"quant\":\"IQ2_XS\"}", + "wait": true, + "status": 200, + "out": { + "ok": true + }, + "job": { + "action": "strata", + "compiled": 0, + "ended_at": "{{T}}", + "error": "l'installeur n'a pas laissé de configuration pour IQ2_XS dans {{HOME}}/strata/ajean-moe-1.0", + "exists": true, + "lines": [ + "ajean-moe-src-1.0.tar.gz déjà téléchargé", + "ajean-moe-engine-1.0-linux-x64-cuda12.zip déjà téléchargé", + "▶ installation de Qwen3.8 Flash Next IQ2_XS (téléchargement de ~68 Go)…", + "installeur : --setup --yes --no-start --no-browser --family qwen --model IQ2_XS --context 131072 --vision gpu --cuda 12 --prebuilt {{HOME}}/strata/prebuilt/ --data-dir {{HOME}}/strata/data --gpu 1 --low-ram off", + "cache : {{HOME}}/strata/cache", + "modèle 10%", + "modèle téléchargé", + "rien d'écrit", + "✗ l'installeur n'a pas laissé de configuration pour IQ2_XS dans {{HOME}}/strata/ajean-moe-1.0" + ], + "new": "", + "next": 9, + "old": "", + "phase": "échec", + "running": false, + "started_at": "{{T}}" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- {\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"{{HOME}}/strata/data/packs/swift-iq3_xxs\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "configuration de lancement disparue", + "files": { + "strata/ajean-moe-1.0/strata-swift-iq3_xxs.json": "-" + }, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "active": true, + "disk_gb": 75.799997999, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + }, + { + "name": "configuration de lancement illisible", + "files": { + "strata/ajean-moe-1.0/strata-swift-iq3_xxs.json": "[1]" + }, + "method": "GET", + "path": "/api/strata", + "status": 200, + "out": { + "active": true, + "env": { + "avail_gb": 42.94967296, + "disk_free_gb": 400, + "gpus": [ + { + "arch": 86, + "index": 0, + "name": "NVIDIA GeForce RTX 3070", + "vram_gb": 8 + }, + { + "arch": 120, + "index": 1, + "name": "NVIDIA GeForce RTX 5060 Ti", + "vram_gb": 15.9287109375 + } + ], + "helper": 0, + "main": 1, + "python": "3.12", + "ram_gb": 47, + "supported": true + }, + "families": [ + { + "about": "réfléchit moins, répond plus vite", + "fits": [ + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "active": true, + "disk_gb": 75.799997999, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + } + ], + "id": "swift", + "label": "Swift 1.5", + "quants": [ + "IQ2_XS", + "IQ3_XXS" + ], + "recommend": "IQ3_XXS" + }, + { + "about": "le Qwen3.8-Flash-Next original", + "fits": [ + { + "disk_gb": 66.4, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE Q2_0", + "quant": { + "about": "le plus rapide", + "arena_gb": 34, + "download_gb": 66.4, + "id": "Q2_0" + } + }, + { + "disk_gb": 68, + "drop": false, + "mmap": true, + "ok": true, + "preset": "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "quant": { + "about": "un peu plus fidèle, presque aussi rapide", + "arena_gb": 35.5, + "download_gb": 68, + "id": "IQ2_XS" + } + }, + { + "disk_gb": 75.8, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "99 % de la qualité du modèle complet", + "arena_gb": 42.9, + "download_gb": 75.8, + "id": "IQ3_XXS" + } + }, + { + "disk_gb": 83.6, + "drop": false, + "mmap": true, + "ok": true, + "quant": { + "about": "la meilleure qualité, le plus lent", + "arena_gb": 50.3, + "download_gb": 83.6, + "id": "IQ3_S" + } + } + ], + "id": "qwen", + "label": "Classique", + "quants": [ + "Q2_0", + "IQ2_XS", + "IQ3_XXS", + "IQ3_S" + ], + "recommend": "IQ3_XXS" + } + ], + "installed": [ + "STRATA FLASH NEXT CLASSIQUE IQ2_XS", + "STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS", + "STRATA FLASH NEXT CLASSIQUE Q2_0", + "S" + ], + "version": "1.0" + }, + "actions": [], + "after": { + "config/CTX": "131072", + "config/ENGINE": "strata", + "config/STRATA_CONFIG": "{{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json", + "config/STRATA_KV": "fp16" + }, + "tree": [ + "d presets", + "d strata", + "d strata/ajean-moe-1.0", + "d strata/ajean-moe-1.0/.venv", + "d strata/ajean-moe-1.0/.venv/bin", + "d strata/ajean-moe-1.0/engine-cuda12", + "d strata/ajean-moe-1.0/serve", + "d strata/data", + "d strata/data/models", + "d strata/data/models/swift-IQ3_XXS", + "d strata/data/packs", + "d strata/data/packs/swift-iq3_xxs", + "d strata/dl", + "d strata/prebuilt", + "f presets/S.env -rw-r--r-- # NAME=Strata S\nENGINE=strata\nSTRATA_HELPER_GPU=0\nSTRATA_EXPERTS=disk\nCTX=98304\nSTRATA_KV=int8\nSTRATA_SPEC=4\nSTRATA_VISION=0\nSTRATA_HELPER=1\n", + "f presets/STRATA FLASH NEXT CLASSIQUE IQ2_XS.env -rw-r--r-- # NAME=Classique IQ2_XS\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=-1\nSTRATA_EXPERTS=disk\n", + "f presets/STRATA FLASH NEXT CLASSIQUE Q2_0.env -rw-r--r-- ENGINE=moe\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=0\nSTRATA_HELPER_GPU=1\nSTRATA_HELPER=0\nSTRATA_VISION=0\nSTRATA_EXPERTS=ram\n", + "f presets/STRATA FLASH NEXT SWIFT 1.5 IQ3_XXS.env -rw-r--r-- # NAME=Qwen3.8 Flash Next Swift 1.5 IQ3_XXS (Strata)\nENGINE=strata\nSTRATA_CONFIG={{HOME}}/strata/ajean-moe-1.0/strata-swift-iq3_xxs.json\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_VISION=1\nSTRATA_EXPERTS=auto\nSTRATA_DROP=1\nSTRATA_KV=fp16\nSTRATA_KV_RESIDENT=32768\nSTRATA_SPEC=3\nCTX=131072\nREASONING=off\n", + "f presets/llama.env -rw-r--r-- MODEL=/m.gguf\n", + "f strata/ajean-moe-1.0/engine-cuda12/.loki-engine -rw-r--r-- ajean-moe-engine-1.0-linux-x64-cuda12.zip\n", + "f strata/ajean-moe-1.0/serve/server.py -rw-r--r-- # serveur\n", + "f strata/ajean-moe-1.0/setup.py -rw-r--r-- # installeur\n", + "f strata/ajean-moe-1.0/setup.sh -rwxr-xr-x #!/bin/bash\necho \"installeur : $*\"\necho \"cache : $XDG_CACHE_HOME\"\nprintf 'modèle 10%%\\r'\nprintf 'modèle 20%%\\r'\necho \"modèle téléchargé\"\nmkdir -p engine-cuda12 .venv/bin\nfam=\"\"; model=\"\"; data=\"\"\nwhile [ $# -gt 0 ]; do\n case \"$1\" in\n --family) fam=\"$2\"; shift;;\n --model) model=\"$2\"; shift;;\n --data-dir) data=\"$2\"; shift;;\n esac\n shift\ndone\ncase \"$model\" in\nQ2_0) echo \"erreur : téléchargement interrompu\" >&2; exit 3;;\nIQ2_XS) echo \"rien d'écrit\"; exit 0;;\nesac\nlow=$(echo \"$model\" | tr 'A-Z' 'a-z')\nif [ \"$fam\" = \"swift\" ]; then tag=\"swift-$low\"; else tag=\"$low\"; fi\nmkdir -p \"$data/packs/$tag\"\nprintf '{\"exe\":\"engine-cuda12/strata\",\"args\":[\"--pack\",\"%s\",\"--kv\",\"int8\",\"--spec\",\"4\",\"--max-context\",\"131072\",\"--vision\",\"--vram-reserve-mib\",\"700\"],\"vision\":{\"exe\":\"v\",\"gpu\":true},\"gpu\":0,\"port\":8080}\\n' \"$data/packs/$tag\" > \"strata-$tag.json\"\necho \"prêt : strata-$tag.json\"\n", + "f strata/ajean-moe-1.0/strata-swift-iq3_xxs.json -rw-r--r-- [1]", + "f strata/data/models/swift-IQ3_XXS/a.gguf -rw-r--r-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "f strata/data/packs/swift-iq3_xxs/experts.bin -rw-r--r-- x", + "f strata/dl/ajean-moe-engine-1.0-linux-x64-cuda12.zip", + "f strata/dl/ajean-moe-src-1.0.tar.gz", + "f strata/prebuilt/strata-linux-x64-cuda12.zip" + ] + } + ] +} diff --git a/rust/loki-rs/tests/proxy.rs b/rust/loki-rs/tests/proxy.rs index bf94372..2b0a866 100644 --- a/rust/loki-rs/tests/proxy.rs +++ b/rust/loki-rs/tests/proxy.rs @@ -114,6 +114,7 @@ async fn facade(backend: SocketAddr) -> (SocketAddr, oneshot::Sender<()>) { update: false, backends: None, engineimg: None, + strata: None, }; tokio::spawn(loki_rs::proxy::serve(l, cfg, async move { let _ = rx.await; diff --git a/rust/loki-rs/tests/strata.rs b/rust/loki-rs/tests/strata.rs new file mode 100644 index 0000000..a7291ae --- /dev/null +++ b/rust/loki-rs/tests/strata.rs @@ -0,0 +1,356 @@ +//! Lot 25 : Strata tenu par la façade (`LOKI_STRATA=rust`, avec +//! `LOKI_BACKENDS=rust`). +//! +//! Le journal tiré du Go (`internal/loki/parity_strata_test.go` → +//! `tests/parity_strata/strata.json`) est rejoué par une façade : fausses +//! machines dans le PATH des sondes (nvidia-smi, python3), faux /proc/meminfo, +//! place libre imposée, fausse release (sources, moteur, empreintes) et +//! installeur factice ; la bascule finale part au faux Go, qui applique le +//! preset comme `applyPresetFile`. + +mod common; + +use std::collections::BTreeMap; +use std::convert::Infallible; +use std::net::SocketAddr; +use std::path::{Path, PathBuf}; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +use bytes::Bytes; +use common::fakego; +use common::parity::{apply_files, tar_gz, write_file}; +use http_body_util::Full; +use hyper::service::service_fn; +use hyper::{Request, Response}; +use hyper_util::rt::TokioIo; +use loki_rs::backends::Backends; +use loki_rs::backends::probe::Probe; +use loki_rs::strata::api::Strata; +use regex::Regex; +use serde_json::{Value, json}; +use sha2::Digest; +use tokio::net::TcpListener; + +fn fixture() -> Value { + serde_json::from_str(include_str!("parity_strata/strata.json")).expect("journal") +} + +fn s(v: &Value) -> &str { + v.as_str().unwrap_or("") +} + +const TUNE_BUSY: &str = "optimisation en cours (loki tune) : le moteur est réservé aux essais — attends la fin ou annule-la"; + +/// La fausse release : `{status, src, engine}`. +async fn fake_release(rel: Arc>) -> String { + let l = TcpListener::bind("127.0.0.1:0").await.unwrap(); + let addr = l.local_addr().unwrap(); + tokio::spawn(async move { + while let Ok((st, _)) = l.accept().await { + let rel = rel.clone(); + tokio::spawn(async move { + let svc = service_fn(move |req: Request| { + let cur = rel.lock().unwrap().clone(); + async move { + let path = req.uri().path().trim_start_matches('/').to_string(); + let (code, body) = match cur["status"].as_u64() { + Some(c) if c != 0 => (c as u16, Vec::new()), + _ if path == loki_rs::strata::SRC_ASSET => (200, src_bytes(&cur)), + _ if path == loki_rs::strata::ENGINE_ASSET => { + (200, s(&cur["engine"]).as_bytes().to_vec()) + } + _ => (404, Vec::new()), + }; + let mut r = Response::new(Full::new(Bytes::from(body))); + *r.status_mut() = hyper::StatusCode::from_u16(code).unwrap(); + Ok::<_, Infallible>(r) + } + }); + let _ = hyper::server::conn::http1::Builder::new() + .serve_connection(TokioIo::new(st), svc) + .await; + }); + } + }); + format!("http://{addr}") +} + +fn src_bytes(rel: &Value) -> Vec { + tar_gz(rel["src"].as_array().map_or(&[][..], Vec::as_slice)) +} + +fn sha(b: &[u8]) -> String { + hex::encode(sha2::Sha256::digest(b)) +} + +struct Bench { + facade: SocketAddr, + go: Arc, + _stop: tokio::sync::oneshot::Sender<()>, + home: PathBuf, + tools: PathBuf, + root: PathBuf, + strata: Arc, + rel: Arc>, + rel_base: String, + _tmp: Vec, +} + +async fn bench() -> Bench { + let tmp = tempfile::tempdir().unwrap(); + let tools = tempfile::tempdir().unwrap(); + let root = tempfile::tempdir().unwrap(); + let home = tmp.path().to_path_buf(); + let probe = || Probe { + path: Some(vec![tools.path().to_path_buf()]), + root: root.path().to_path_buf(), + }; + std::fs::create_dir_all(root.path().join("proc")).unwrap(); + let rel = Arc::new(Mutex::new(json!({}))); + let rel_base = fake_release(rel.clone()).await; + let b = Arc::new(Backends::with( + home.clone(), + String::new(), + probe(), + String::new(), + )); + let mut st = Strata::new(home.clone(), probe()); + st.release_base = format!("{rel_base}/"); + st.platform_ok = true; + let strata = Arc::new(st); + let (facade, go, stop, _) = fakego::start_with( + home.clone(), + fakego::Opts { + backends: Some(b), + strata: Some(strata.clone()), + ..Default::default() + }, + ) + .await; + *go.apply_presets.lock().unwrap() = true; + Bench { + facade, + go, + _stop: stop, + home, + tools: tools.path().to_path_buf(), + root: root.path().to_path_buf(), + strata, + rel, + rel_base, + _tmp: vec![tmp, tools, root], + } +} + +impl Bench { + fn mask(&self, v: &str) -> String { + let ts = Regex::new(r#""(started_at|ended_at)":[1-9][0-9]*"#).unwrap(); + let v = v + .replace(&self.rel_base, "{{REL}}") + .replace(&self.home.to_string_lossy().into_owned(), "{{HOME}}"); + ts.replace_all(&v, r#""$1":"{{T}}""#).into_owned() + } + + fn unmask(&self, v: &str) -> String { + v.replace("{{HOME}}", &self.home.to_string_lossy()) + } + + async fn call(&self, method: &str, path: &str, body: &str) -> (u16, Value) { + let (code, b) = fakego::send(self.facade, method, path, &[], body).await; + let out = serde_json::from_str(&self.mask(&String::from_utf8_lossy(&b))) + .unwrap_or_else(|_| panic!("{path} : corps illisible {b:?}")); + (code.as_u16(), out) + } + + async fn wait_job(&self) { + for _ in 0..1500 { + let (_, v) = self.call("GET", "/api/llamacpp/job", "").await; + if v["running"] != json!(true) { + return; + } + tokio::time::sleep(Duration::from_millis(20)).await; + } + panic!("le job ne finit pas"); + } + + /// Les outils d'une machine (bash, mkdir et tr toujours). + fn set_machine(&self, machines: &Value, name: &str) { + for e in std::fs::read_dir(&self.tools).unwrap().flatten() { + std::fs::remove_file(e.path()).unwrap(); + } + for tool in ["bash", "mkdir", "tr"] { + let p = loki_rs::paths::look_path(tool).expect(tool); + std::os::unix::fs::symlink(p, self.tools.join(tool)).unwrap(); + } + for (tool, script) in machines[name].as_object().into_iter().flatten() { + write_file(&self.tools.join(tool), s(script), 0o755); + } + } + + fn set_release(&self, r: &Value) { + *self.rel.lock().unwrap() = r.clone(); + let mut want = std::collections::HashMap::from([ + (loki_rs::strata::SRC_ASSET.to_string(), sha(&src_bytes(r))), + ( + loki_rs::strata::ENGINE_ASSET.to_string(), + sha(s(&r["engine"]).as_bytes()), + ), + ]); + if r["bad_sha"] == json!(true) { + want.insert(loki_rs::strata::ENGINE_ASSET.to_string(), "0".repeat(64)); + } + *self.strata.asset_sha.lock().unwrap() = want; + } + + /// presets/ et strata/, sans le contenu des archives. + fn tree(&self) -> Vec { + use std::os::unix::fs::PermissionsExt; + fn walk(b: &Bench, p: &Path, out: &mut Vec) { + let Ok(m) = std::fs::symlink_metadata(p) else { + return; + }; + let rel = p + .strip_prefix(&b.home) + .unwrap() + .to_string_lossy() + .into_owned(); + if m.is_dir() { + out.push(format!("d {rel}")); + for e in std::fs::read_dir(p).unwrap().flatten() { + walk(b, &e.path(), out); + } + } else if rel.starts_with("strata/dl/") || rel.starts_with("strata/prebuilt/") { + out.push(format!("f {rel}")); + } else { + let c = std::fs::read(p).unwrap(); + out.push(format!( + "f {rel} {} {}", + common::parity::perm_string(m.permissions().mode() & 0o777), + b.mask(&String::from_utf8_lossy(&c)) + )); + } + } + let mut out = Vec::new(); + for root in ["presets", "strata"] { + walk(self, &self.home.join(root), &mut out); + } + out.sort(); + out + } +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn parite_de_strata() { + if !cfg!(target_arch = "x86_64") { + eprintln!("Strata n'est proposé que sous Linux x86_64 : rejeu sauté"); + return; + } + let fx = fixture(); + let bn = bench().await; + let machines = &fx["machines"]; + for st in fx["steps"].as_array().unwrap() { + let name = s(&st["name"]); + if let Some(m) = st["machine"].as_str() { + bn.set_machine(machines, m); + } + if let Some(m) = st["meminfo"].as_str() { + std::fs::write(bn.root.join("proc/meminfo"), m).unwrap(); + } + if let Some(d) = st["disk_free"].as_i64() { + *bn.strata.disk_free.lock().unwrap() = Some(d); + } + let files: serde_json::Map = st["files"] + .as_object() + .into_iter() + .flatten() + .map(|(k, v)| (k.clone(), Value::String(bn.unmask(s(v))))) + .collect(); + apply_files(&bn.home, &Value::Object(files)); + for (k, v) in st["config"].as_object().into_iter().flatten() { + let v = bn.unmask(s(v)); + if v.is_empty() { + bn.go.del("config", k); + } else { + bn.go.set("config", k, &v); + } + } + for (k, v) in st["state"].as_object().into_iter().flatten() { + if s(v).is_empty() { + bn.go.del("state", k); + } else { + bn.go.set("state", k, s(v)); + } + } + if !st["release"].is_null() { + bn.set_release(&st["release"]); + } + bn.go.preset_applies.lock().unwrap().clear(); + *bn.go.tune_busy.lock().unwrap() = + (st["tune"].as_bool() == Some(true)).then(|| TUNE_BUSY.to_string()); + let (code, out) = bn + .call(s(&st["method"]), s(&st["path"]), &bn.unmask(s(&st["body"]))) + .await; + *bn.go.tune_busy.lock().unwrap() = None; + assert_eq!(code as i64, st["status"].as_i64().unwrap(), "{name}"); + assert_eq!(out, st["out"], "{name}"); + if st["wait"].as_bool() == Some(true) { + bn.wait_job().await; + let (_, job) = bn.call("GET", "/api/llamacpp/job?from=0", "").await; + assert_eq!(job, st["job"], "{name} : job"); + } + // Une bascule faite par le Go : application du preset puis + // redémarrage du service. + let actions: Vec = bn + .go + .preset_applies + .lock() + .unwrap() + .iter() + .filter(|(_, mode)| mode == "switch") + .map(|_| json!("restart")) + .collect(); + assert_eq!(Value::Array(actions), st["actions"], "{name} : service"); + let mut after = BTreeMap::new(); + for k in [ + "ENGINE", + "STRATA_CONFIG", + "CTX", + "STRATA_KV", + "STRATA_HELPER", + ] { + if let Some(v) = bn.go.get("config", k).filter(|v| !v.is_empty()) { + after.insert(format!("config/{k}"), Value::String(bn.mask(&v))); + } + } + assert_eq!( + Value::Object(after.into_iter().collect()), + st["after"], + "{name} : après" + ); + let t: Vec = bn.tree().into_iter().map(Value::String).collect(); + let t = if t.is_empty() { + Value::Null + } else { + Value::Array(t) + }; + assert_eq!(t, st["tree"], "{name} : arborescence"); + } +} + +/// Sans les backends dans la façade (pas de job), Strata répond 503. +#[tokio::test] +async fn sans_backends() { + let tmp = tempfile::tempdir().unwrap(); + let st = Strata::new(tmp.path().to_path_buf(), Probe::system()); + let (facade, _go, _stop, _) = fakego::start_with( + tmp.path().to_path_buf(), + fakego::Opts { + strata: Some(Arc::new(st)), + ..Default::default() + }, + ) + .await; + let (c, b) = fakego::send(facade, "GET", "/api/strata", &[], "").await; + assert_eq!(c.as_u16(), 503, "{b:?}"); +}