mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-17 20:26:35 +02:00
Repris d'AJEAN 38919238 (#121 amont) et de la partie moteur de 6db3f3d0 : STRATA_SPLIT=layers dans le preset fait lister les deux cartes dans la clé « gpu » de la config (principale d'abord, numéros nvidia-smi) ; le serveur de Strata en déduit --layer-split. Rien du mode d'aide ne subsiste alors : ni --expert-cache-device1 / --remote-expert-opt, ni source d'aide à la lecture des prompts, ni encodeur d'images déplacé ; la réserve de VRAM de l'installeur reste. Sans la clé, ou la seconde carte coupée, rien ne change. Propre à Loki : le placement des experts selon la RAM disponible ne choisit jamais le mode hors RAM en partage des couches (la seconde carte n'y garde pas d'experts, la marge calculée pour elle serait fausse). Réglages : « split » (helper ou layers ; absent = inchangé pour un ancien client), détail split_layers. Fenêtre Strata : la case « Carte d'appoint » devient un choix « Seconde carte » (non utilisée, aide aux experts, partage des couches) ; la carte de configuration du moteur actif l'affiche. Façade Rust alignée (strata/mod.rs, strata/api.rs, tests portés) ; journal de parité régénéré sous Linux avec les réglages et l'affichage du partage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
125 lines
5.0 KiB
Go
125 lines
5.0 KiB
Go
package loki
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// Partage des couches (#121 amont) : la clé « gpu » liste les deux cartes (le
|
|
// serveur de Strata en déduit --layer-split), et rien du mode d'aide ne subsiste.
|
|
func TestStrataBuildConfigLayerSplit(t *testing.T) {
|
|
base := map[string]any{
|
|
"args": []any{"--pack", "/p", "--vram-reserve-mib", "900"},
|
|
"vision": map[string]any{"exe": "/v"},
|
|
}
|
|
cfg := map[string]string{"STRATA_MAIN_GPU": "1", "STRATA_HELPER_GPU": "0", "STRATA_SPLIT": "layers"}
|
|
out, err := strataBuildConfig(base, cfg, "", "drop")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
g, ok := out["gpu"].([]any)
|
|
if !ok || len(g) != 2 || g[0] != 1 || g[1] != 0 {
|
|
t.Fatalf("gpu = %v, attendu [1 0] (principale d'abord, numéros nvidia-smi)", out["gpu"])
|
|
}
|
|
a := strataArgs(t, out)
|
|
if strataHasArg(a, "--remote-expert-opt") || strataHasArg(a, "--expert-cache-device1") {
|
|
t.Errorf("options du mode d'aide en partage des couches : %v", a)
|
|
}
|
|
if argAfter(a, "--vram-reserve-mib") != "900" {
|
|
t.Errorf("la réserve de VRAM de l'installeur doit rester : %v", a)
|
|
}
|
|
if argAfter(a, "--short-read") != "150" {
|
|
t.Errorf("lecture des prompts par la carte d'aide en partage des couches : %v", a)
|
|
}
|
|
env := out["env"].(map[string]any)
|
|
if env["STRATA_REMOTE_DROP"] != nil || env["STRATA_PREFILL_HELPER_SOURCE"] != nil {
|
|
t.Errorf("experts hors RAM ou source d'aide (mode d'aide) en partage des couches : %v", env)
|
|
}
|
|
if _, has := out["vision"].(map[string]any)["cuda_device"]; has {
|
|
t.Errorf("encodeur d'images déplacé sur la seconde carte en partage des couches")
|
|
}
|
|
|
|
// Sans la clé, rien ne change : le mode d'aide reste le défaut.
|
|
delete(cfg, "STRATA_SPLIT")
|
|
out, _ = strataBuildConfig(base, cfg, "", "drop")
|
|
if _, has := out["gpu"]; has {
|
|
t.Errorf("clé gpu posée en mode d'aide : %v", out["gpu"])
|
|
}
|
|
if !strataHasArg(strataArgs(t, out), "--remote-expert-opt") {
|
|
t.Errorf("mode d'aide perdu sans STRATA_SPLIT")
|
|
}
|
|
// Seconde carte coupée : pas de partage même si la clé traîne.
|
|
cfg["STRATA_SPLIT"], cfg["STRATA_HELPER"] = "layers", "0"
|
|
if strataLayerSplit(cfg) {
|
|
t.Errorf("partage des couches avec la seconde carte coupée")
|
|
}
|
|
}
|
|
|
|
// En partage des couches, la seconde carte ne garde pas d'experts : le mode
|
|
// hors RAM (qui compte sur elle pour en loger une part) n'est jamais choisi.
|
|
func TestStrataResolveExpertsLayerSplit(t *testing.T) {
|
|
home := t.TempDir()
|
|
t.Setenv("LOKI_HOME", home)
|
|
pack := filepath.Join(home, "pack")
|
|
_ = os.MkdirAll(pack, 0o755)
|
|
_ = os.WriteFile(filepath.Join(pack, "experts.bin"), []byte("x"), 0o644)
|
|
_ = os.MkdirAll(filepath.Join(strataSrcDir(), "engine-cuda12"), 0o755)
|
|
_ = os.WriteFile(strataEngineMarker(), []byte(strataEngineAsset+"\n"), 0o644)
|
|
args := []string{"--pack", pack}
|
|
cfg := map[string]string{"STRATA_CONFIG": "/x/strata-swift-iq3_xxs.json", "STRATA_HELPER_GPU": "1", "STRATA_DROP": "1"}
|
|
if got := strataResolveExperts(cfg, args, 44, 12); got != "drop" {
|
|
t.Fatalf("mode d'aide : %s, attendu drop", got)
|
|
}
|
|
cfg["STRATA_SPLIT"] = "layers"
|
|
if got := strataResolveExperts(cfg, args, 44, 12); got != "arena" {
|
|
t.Errorf("partage des couches : %s, attendu arena", got)
|
|
}
|
|
cfg["STRATA_EXPERTS"] = "ram"
|
|
if got := strataResolveExperts(cfg, args, 44, 12); got != "ram" {
|
|
t.Errorf("partage des couches, experts en RAM : %s, attendu ram", got)
|
|
}
|
|
}
|
|
|
|
func TestStrataApplySettingsSplit(t *testing.T) {
|
|
in := "ENGINE=strata\nSTRATA_HELPER_GPU=0\n"
|
|
req := strataSettingsReq{Ctx: 131072, KV: "fp16", Spec: 3, Vision: true, Helper: true, Split: "layers"}
|
|
out, err := strataApplySettings(in, req)
|
|
if err != nil || !strings.Contains(out, "STRATA_SPLIT=layers\n") {
|
|
t.Fatalf("STRATA_SPLIT=layers attendu : %q (%v)", out, err)
|
|
}
|
|
req.Split = "helper"
|
|
if out, _ = strataApplySettings(out, req); strings.Contains(out, "STRATA_SPLIT") {
|
|
t.Errorf("retour au mode d'aide : la clé doit disparaître : %q", out)
|
|
}
|
|
// un ancien client n'envoie pas « split » : la clé est conservée
|
|
req.Split = ""
|
|
out, _ = strataApplySettings("STRATA_SPLIT=layers\n", req)
|
|
if !strings.Contains(out, "STRATA_SPLIT=layers") {
|
|
t.Errorf("clé effacée par un client qui ne la connaît pas : %q", out)
|
|
}
|
|
req.Split = "nimporte"
|
|
if _, err := strataApplySettings(in, req); err == nil {
|
|
t.Errorf("répartition inconnue acceptée")
|
|
}
|
|
}
|
|
|
|
func TestStrataDetailsForLayerSplit(t *testing.T) {
|
|
home := t.TempDir()
|
|
t.Setenv("LOKI_HOME", home)
|
|
base := filepath.Join(home, "base.json")
|
|
_ = os.WriteFile(base, []byte(`{"args":["--pack","/p"],"vision":{"exe":"v"}}`), 0o644)
|
|
_ = os.MkdirAll(presetsDir(), 0o755)
|
|
preset := "ENGINE=strata\nSTRATA_CONFIG=" + base + "\nSTRATA_MAIN_GPU=1\nSTRATA_HELPER_GPU=0\nSTRATA_SPLIT=layers\n"
|
|
_ = os.WriteFile(filepath.Join(presetsDir(), "X.env"), []byte(preset), 0o644)
|
|
env := strataEnv{GPUs: []strataGPU{{Index: 0, Name: "NVIDIA GeForce RTX 3060", VRAMGB: 12}, {Index: 1, Name: "NVIDIA GeForce RTX 3060", VRAMGB: 12}}}
|
|
d := strataDetailsFor("X", env)
|
|
if d == nil {
|
|
t.Fatal("pas de détails")
|
|
}
|
|
if !d.Split || !d.HelperOn || d.HelperGPU == "" || d.VisionGPU != d.MainGPU || d.ShortRead != "150" {
|
|
t.Errorf("%+v", *d)
|
|
}
|
|
}
|