mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 22:48:11 +02:00
Moteur : LOAD_GUARD ne refuse plus sur la seule VRAM NVIDIA (Vulkan, cartes mixtes)
La borne basse des poids en RAM se calculait avec la VRAM de nvidia-smi. Un moteur Vulkan sur une machine NVIDIA + AMD, sans --device, place aussi des poids sur la carte AMD : la borne était fausse et le lancement refusé à tort. Un moteur ROCm à côté d'une carte NVIDIA n'utilise pas du tout celle-ci. - Le refus se décide désormais sur les cartes que le moteur liste lui-même (--list-devices, dans l'environnement du lancement, sélection GPU comprise), toutes additionnées : rien au-delà ne peut recevoir de poids, la borne est sûre. Une carte listée sans servir (iGPU) ne fait que rendre le refus plus rare. - Lu seulement quand un refus se profile sur la VRAM NVIDIA : aucun lancement de plus dans le cas ordinaire. Les cartes de SPLIT_MODE sont reprises si elles sont déjà lues. - Liste illisible, vide ou carte à 0 Mio (déjà pleine) : avertissement, jamais de refus. Même chose dans l'aperçu de l'éditeur, qui reprend la dernière liste complète du moteur (devices.json) sans le lancer. - Le reste ne bouge pas : VRAM inconnue, --device, --rpc, mémoire unifiée. - Tests : faux refus Vulkan évité, nvidia-smi seul n'est qu'un avis, lecture déclenchée seulement avec un refus en vue, somme des cartes (JSON relu). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a4db6d4da1
commit
f0fef91773
5 files changed
+164
-16
No files matched your search
@@ -98,17 +98,39 @@ func probeSplit(cfg map[string]string, bin string, si *serveSysInfo) {
|
||||
if v := os.Getenv("GGML_CUDA_ALLREDUCE"); v != "" {
|
||||
si.UserEnv["GGML_CUDA_ALLREDUCE"] = v
|
||||
}
|
||||
si.SplitDevs = listEngineDevices(bin)
|
||||
}
|
||||
|
||||
// listEngineDevices : les cartes que CE moteur voit (--list-devices), dans
|
||||
// l'environnement du processus — celui du vrai lancement quand cmdServe
|
||||
// appelle. nil si le moteur échoue : sortie tronquée (carte pleine, moteur
|
||||
// planté), on ne s'y fie pas.
|
||||
func listEngineDevices(bin string) []splitDev {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
out, err := hideCmd(exec.CommandContext(ctx, bin, "--list-devices")).CombinedOutput()
|
||||
if err != nil {
|
||||
return // sortie tronquée (carte pleine, moteur planté) : on ne s'y fie pas
|
||||
return nil
|
||||
}
|
||||
for _, d := range parseListDevices(string(out)) {
|
||||
return splitDevsFrom(parseListDevices(string(out)))
|
||||
}
|
||||
|
||||
// splitDevsFrom : les cartes de parseListDevices (ou de devices.json, relu en
|
||||
// JSON : les nombres y sont des float64).
|
||||
func splitDevsFrom(list []map[string]any) []splitDev {
|
||||
var devs []splitDev
|
||||
for _, d := range list {
|
||||
id, _ := d["id"].(string)
|
||||
total, _ := d["total_mib"].(int)
|
||||
si.SplitDevs = append(si.SplitDevs, splitDev{ID: id, TotalMiB: int64(total)})
|
||||
var total int64
|
||||
switch v := d["total_mib"].(type) {
|
||||
case int:
|
||||
total = int64(v)
|
||||
case float64:
|
||||
total = int64(v)
|
||||
}
|
||||
devs = append(devs, splitDev{ID: id, TotalMiB: total})
|
||||
}
|
||||
return devs
|
||||
}
|
||||
|
||||
// splitPlan décide de SPLIT_MODE=tensor pour ce lancement. Fonction pure.
|
||||
|
||||
Reference in new issue
Block a user