mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-17 04:10:04 +02:00
Préchargement des modèles : warm + keep_alive + indicateur d'état
Évite le rechargement lent quand Ollama a déchargé le modèle de la VRAM : - ollama_client.warm() : précharge un modèle (/api/generate sans prompt) ; chat() accepte keep_alive (durée de rétention en VRAM). - agent.run_agent transmet keep_alive ; route chat le passe depuis la config. - config : champ keep_alive (défaut 30m) par profil de modèle. - routes/models : POST /api/models/warm, GET /api/models/loaded (placement GPU/CPU via /api/ps). - main : préchargement du modèle par défaut au démarrage (arrière-plan, best-effort — n'empêche pas le démarrage si Ollama est absent). - Frontend : préchargement automatique à la sélection d'un modèle, poll des modèles chargés (8s), pastille verte (GPU) / orange (CPU) / blanche (à charger) dans le sélecteur, réglage 'Maintien en VRAM' dans Configuration. Tests : warm/loaded routes, keep_alive transmis, démarrage résilient sans Ollama, build front. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
This commit is contained in:
12 files changed
+205
-8
No files matched your search
@@ -4,10 +4,14 @@ import { ChevronDown } from "./Icon";
|
||||
|
||||
/** Sélecteur de modèle Ollama (chip orange de la barre supérieure). */
|
||||
export function ModelSelector() {
|
||||
const { models, selectedModel, setSelectedModel } = useStore();
|
||||
const { models, selectedModel, setSelectedModel, loadedModels } = useStore();
|
||||
const [open, setOpen] = useState(false);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
const loadedInfo = (name: string) =>
|
||||
loadedModels.find((m) => m.name === name);
|
||||
const selectedLoaded = loadedInfo(selectedModel);
|
||||
|
||||
useEffect(() => {
|
||||
const onClick = (e: MouseEvent) => {
|
||||
if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
|
||||
@@ -24,7 +28,22 @@ export function ModelSelector() {
|
||||
title={selectedModel || undefined}
|
||||
style={{ borderRadius: 7 }}
|
||||
>
|
||||
<span className="h-2.5 w-2.5 border-2 border-line bg-white" />
|
||||
<span
|
||||
className={`h-2.5 w-2.5 border-2 border-line ${
|
||||
selectedLoaded
|
||||
? selectedLoaded.on_gpu
|
||||
? "bg-ok"
|
||||
: "bg-warn"
|
||||
: "bg-white"
|
||||
}`}
|
||||
title={
|
||||
selectedLoaded
|
||||
? selectedLoaded.on_gpu
|
||||
? "chargé sur GPU"
|
||||
: `chargé (${selectedLoaded.gpu_percent}% GPU)`
|
||||
: "à charger"
|
||||
}
|
||||
/>
|
||||
<span className="min-w-0 truncate text-[14px] leading-none">{selectedModel || "—"}</span>
|
||||
<ChevronDown size={12} className="flex-none" />
|
||||
</button>
|
||||
@@ -55,6 +74,14 @@ export function ModelSelector() {
|
||||
<span className="min-w-0 flex-1 truncate text-xs text-ink-2" title={m.name}>
|
||||
{m.name}
|
||||
</span>
|
||||
{loadedInfo(m.name) && (
|
||||
<span
|
||||
className={`h-1.5 w-1.5 border border-line ${
|
||||
loadedInfo(m.name)!.on_gpu ? "bg-ok" : "bg-warn"
|
||||
}`}
|
||||
title={loadedInfo(m.name)!.on_gpu ? "chargé GPU" : "chargé CPU"}
|
||||
/>
|
||||
)}
|
||||
{m.size_go > 0 && (
|
||||
<span className="text-[10px] text-muted-2">{m.size_go} Go</span>
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user