From af98b4701837bceb95b1d6024faad79791ac059a Mon Sep 17 00:00:00 2001 From: ALI YESILKAYA Date: Sun, 21 Jun 2026 23:29:05 +0200 Subject: [PATCH] =?UTF-8?q?docs(cluster):=20aligne=20la=20doc=20sur=20l'?= =?UTF-8?q?=C3=A9tat=20r=C3=A9el=20+=20re-ingest=20RAG=20+=20fix=20ubatch?= =?UTF-8?q?=20embed=20(#44)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(rag): ubatch=2048 pour llama-embed + retry rag-ingest + nettoie defaults rag L'instance llama-embed (:1238) tournait avec l'ubatch llama.cpp par défaut (512). En mode --embeddings + pooling, toute l'entrée doit tenir dans un seul ubatch → tout chunk > 512 tokens échouait en HTTP 500 « input too large to process. increase the physical batch size ». ~46 chunks du RAG (CHUNK_MAX=2000 chars ≈ 700 tokens) n'étaient pas indexés. - llama_server : ajoute llama_embed_ubatch_size (2048 = ctx) + flags --batch-size/--ubatch-size dans le template llama-embed.service. - rag-ingest : retry (5×, backoff) sur erreurs transitoires 5xx/réseau de l'embed. - rag/defaults : aligne embed_url/embed_model sur nomic :1238 (étaient des vars mortes pointant encore qwen3-8b :1234 — trompeuses). Résultat : ré-ingestion 436/436 chunks, 0 erreur. Co-Authored-By: Claude Opus 4.8 * docs(cluster): aligne la doc sur l'état réel (relevé 2026-06-21) + snapshot Passe de vérification terrain (SSH s01/g01 + kubectl) pour corriger les écarts doc↔réalité, et ajout d'un document de référence vérifié. - admin/ops/etat-cluster.md (nouveau) : snapshot daté — machines, services+ports par hôte, workloads k8s, namespaces, IngressRoute, bases PG, modèles LiteLLM, RAG/Qdrant, + procédure pour régénérer le relevé. - OS AlmaLinux 9.7 → 9.8 (s01/g01) ; précise k8s v1.33.1 (CLAUDE/README/install/talos). - RAG funk-docs : retire le warning périmé « supprimée 2026-06-17 / à re-ingérer » → reconstruite (436 chunks, nomic-embed-text :1238 dim 768, CPU). Maj rag.md, incidents.md, stt.md. - Namespace sacrifice (hors-repo, hors ArgoCD) + bases PG grafana/sacrifice + services ai via IngressRoute + registry in-cluster (CLAUDE.md, k9s.md). - Services de résilience (llm-heartbeat, llama-watchdog/embed) et instances CPU manuelles :1236/:1237 (souvent éteintes) documentés. - Journal progress/2026-06-21.md : section relevé + RAG. Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 --- CLAUDE.md | 26 +-- README.md | 20 +-- admin/ia/rag.md | 67 +++---- admin/ia/stt.md | 4 +- admin/incidents.md | 11 +- admin/install/README.md | 6 +- admin/install/gpu-01.md | 2 +- admin/k8s/k9s.md | 7 +- admin/k8s/talos.md | 2 +- admin/ops/etat-cluster.md | 167 ++++++++++++++++++ ansible/roles/llama_server/defaults/main.yml | 5 + .../templates/llama-embed.service.j2 | 2 + ansible/roles/rag/defaults/main.yml | 8 +- ansible/roles/rag/files/rag-ingest | 19 +- progress/2026-06-21.md | 28 ++- 15 files changed, 292 insertions(+), 82 deletions(-) create mode 100644 admin/ops/etat-cluster.md diff --git a/CLAUDE.md b/CLAUDE.md index b707b83..5069bad 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,10 +8,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co **État actuel (2026-06-21)** : - ✅ Hermes Agent opérationnel — multi-profils (funk-ai/system/monitor/brain) -- ✅ Qdrant réparé (2026-06-17) — fin du crash-loop (segment `funk-docs` corrompu, voir `admin/incidents.md`). ⚠️ La collection RAG `funk-docs` a été supprimée lors de la réparation → **re-`rag-ingest` requis** pour réactiver `rag-query` +- ✅ Qdrant réparé (2026-06-17) — fin du crash-loop (segment `funk-docs` corrompu, voir `admin/incidents.md`). La collection RAG `funk-docs` a depuis été **reconstruite** (436 chunks, 🟢 green, embeddings nomic-embed-text dim 768) — `rag-query` opérationnel - ✅ Monitoring complet — Prometheus + Grafana + AlertManager → webhook Hermes + n8n - ✅ storage-01 installé — `192.168.10.1` (LAN cluster), `192.168.1.200` (WAN) -- ✅ gpu-01 installé — llama-server GPU (:1234) + CPU (:1236/:1237) + embeddings dédiés nomic-embed-text (:1238, GPU) opérationnels, kernel 5.14.0-687.5.3 +- ✅ gpu-01 installé — llama-server GPU (:1234, qwen3-8b) + embeddings dédiés nomic-embed-text (:1238, **CPU** — découplé du slot chat GPU) + watchdog/heartbeat de résilience, kernel 5.14.0-687.5.3. ⚠️ Les instances CPU (:1236/:1237 — profils Hermes `system`/`monitor`) sont **manuelles** et souvent éteintes (gap IaC) - ✅ LiteLLM sur storage-01 — proxy multi-modèles + ask-agent (écoute `0.0.0.0:4000`) - ✅ Cluster k8s Talos opérationnel (MetalLB + Traefik + wildcard DNS lab.local) - ✅ postfix_relay — SMTP sortant via Gmail SMTP + App Password (aliyesilkaya93@gmail.com) @@ -30,11 +30,13 @@ Journal de progression : `PROGRESS.md` → `progress/YYYY-MM-DD.md` | Machine | IP | OS | Rôle | |---|---|---|---| -| storage-01 | 192.168.10.1 / 192.168.1.200 | AlmaLinux 9.7 | Passerelle + bastion admin + données + Hermes Agent — **hors cluster** | -| compute-01 | 192.168.10.11 | Talos v1.13 | k8s control-plane | -| compute-02 | 192.168.10.12 | Talos v1.13 | k8s worker | -| compute-03 | 192.168.10.13 | Talos v1.13 | k8s worker | -| gpu-01 | 192.168.10.20 | AlmaLinux 9.7 | llama-server dédié (RX 6700XT, ROCm 7.x) — **hors cluster** | +| storage-01 | 192.168.10.1 / 192.168.1.200 | AlmaLinux 9.8 | Passerelle + bastion admin + données + Hermes Agent — **hors cluster** | +| compute-01 | 192.168.10.11 | Talos v1.13 (k8s v1.33.1) | k8s control-plane | +| compute-02 | 192.168.10.12 | Talos v1.13 (k8s v1.33.1) | k8s worker | +| compute-03 | 192.168.10.13 | Talos v1.13 (k8s v1.33.1) | k8s worker | +| gpu-01 | 192.168.10.20 | AlmaLinux 9.8 | llama-server dédié (RX 6700XT, ROCm 7.x) — **hors cluster** | + +> 📸 État live vérifié (services, ports, workloads, bases, RAG) : **`admin/ops/etat-cluster.md`** (snapshot 2026-06-21). **Points clés d'architecture :** - `storage-01` et `gpu-01` sont **hors du cluster k8s** — consommés via `ExternalName` services ou `Endpoints` manuels @@ -179,7 +181,9 @@ k8s/ 2. Créer `k8s/apps-of-apps/apps/.yaml` (ArgoCD Application CRD) — copier `n8n.yaml` comme modèle 3. `git commit` + `git push` → ArgoCD prend en charge automatiquement -Namespaces actifs : `argocd`, `infra` (Traefik, MetalLB, NFS-provisioner), `monitoring` (Prometheus/Grafana), `ai` (n8n, open-webui, stt, ghostfolio). +Namespaces actifs : `argocd`, `infra` (Traefik, MetalLB, NFS-provisioner, registry in-cluster), `monitoring` (Prometheus/Grafana), `ai` (n8n, open-webui, stt, ghostfolio), `sacrifice` (jeu FPS — déployé hors de ce repo et hors ArgoCD, cf. `admin/ops/etat-cluster.md`). + +> Les services du namespace `ai` sont exposés via des **IngressRoute Traefik** (CRD), pas des `Ingress` standards. --- @@ -220,9 +224,9 @@ ask-agent monitor "logs litellm : — erreurs ?" ### RAG — Documentation Funk -> ⚠️ **Qdrant réparé le 2026-06-17** (fin du crash-loop, segment `funk-docs` corrompu — voir `admin/incidents.md`). La réparation a **supprimé** la collection `funk-docs` sans la reconstruire → relancer `rag-ingest` pour réactiver `rag-query`. Le service Qdrant et la mémoire long-terme STT (`stt-memory`) sont opérationnels. +> ✅ **`funk-docs` reconstruite et opérationnelle** (relevé 2026-06-21 : **436 chunks**, 🟢 green). Le warning « collection supprimée le 2026-06-17, re-ingest requis » est **périmé** : elle a été ré-indexée depuis. Qdrant et la mémoire long-terme STT (`stt-memory`) sont opérationnels. -Qdrant collection `funk-docs` indexée depuis `admin/` (≈339 chunks avant suppression, score min 0.60 ; à re-ingérer). +Qdrant collection `funk-docs` indexée depuis `admin/` (436 chunks, embeddings **nomic-embed-text** `:1238` dim 768 — plus qwen3-8b ; score min ajusté pour nomic dans `rag-query`). ```bash rag-query "comment relancer dnsmasq ?" @@ -333,6 +337,6 @@ talosctl etcd snapshot /path/to/backup.db --nodes compute-01 - **Git** : branches `main` (prod) / `feature/*` — conventional commits (`feat:`, `fix:`, `chore:`, `docs:`) - **Secrets** : Ansible Vault (Ansible), SOPS+age (Talos), Sealed Secrets (k8s) -- **Namespaces k8s** : `argocd`, `infra`, `monitoring`, `ai`, `external` +- **Namespaces k8s** : `argocd`, `infra`, `monitoring`, `ai`, `external` (+ `sacrifice`, hors-repo) - **Hermes data** : profils/données dans `/srv/data/hermes` (NVMe, bind-mount `/home/data`), code dans `/opt/hermes/` (SSD OS) - **RAM compute-02/03** : toujours définir `resources.requests` + `resources.limits` (8 GB RAM, OOM-killer actif) diff --git a/README.md b/README.md index 1ef49d6..0c79749 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ L'ensemble est géré en Infrastructure-as-Code : **Ansible** pour les hôtes Al | Composant | Rôle | Hôte | |---|---|---| -| **llama-server** (×4) | Inférence GPU (:1234) + 2× CPU isolés (:1236/:1237) + embeddings dédiés nomic-embed-text (:1238) — ROCm 7.x | gpu-01 | +| **llama-server** | Inférence GPU (:1234, qwen3-8b — ROCm 7.x) + embeddings dédiés nomic-embed-text (:1238, CPU) + watchdog/heartbeat. Instances CPU :1236/:1237 (profils `system`/`monitor`) **manuelles, souvent éteintes** | gpu-01 | | **LiteLLM** | Proxy API — routing local/cloud transparent | storage-01 | | **Hermes Agent** | Agent IA multi-profils avec mémoire vectorielle | storage-01 | | **ask-agent** | Délégation inter-agents (system / monitor / brain) | storage-01 | @@ -108,11 +108,11 @@ L'ensemble est géré en Infrastructure-as-Code : **Ansible** pour les hôtes Al | Machine | IP | OS | RAM | Rôle | |---|---|---|---|---| -| storage-01 | 192.168.10.1 | AlmaLinux 9.7 | 32 GB | Gateway · NFS · Services IA | -| gpu-01 | 192.168.10.20 | AlmaLinux 9.7 | 32 GB | Inférence LLM (RX 6700XT) | -| compute-01 | 192.168.10.11 | Talos v1.13 | 16 GB | k8s control-plane | -| compute-02 | 192.168.10.12 | Talos v1.13 | 8 GB | k8s worker | -| compute-03 | 192.168.10.13 | Talos v1.13 | 8 GB | k8s worker | +| storage-01 | 192.168.10.1 | AlmaLinux 9.8 | 32 GB | Gateway · NFS · Services IA | +| gpu-01 | 192.168.10.20 | AlmaLinux 9.8 | 32 GB | Inférence LLM (RX 6700XT) | +| compute-01 | 192.168.10.11 | Talos v1.13 (k8s v1.33.1) | 16 GB | k8s control-plane | +| compute-02 | 192.168.10.12 | Talos v1.13 (k8s v1.33.1) | 8 GB | k8s worker | +| compute-03 | 192.168.10.13 | Talos v1.13 (k8s v1.33.1) | 8 GB | k8s worker | ### Stockage @@ -248,7 +248,7 @@ Elle est gérée automatiquement par le rôle Ansible `llama_server`. - [x] Ansible — gpu-01 (ROCm, llama-server : GPU :1234 + embeddings :1238 via le rôle ; 2× CPU manuels) - [x] Stack IA opérationnelle (Hermes multi-profils + Qwen3 + Claude API) - [x] Délégation inter-agents (`ask-agent` + skill `agent-delegation`) -- [x] RAG opérationnel — Qdrant 339 chunks, `rag-query` / `rag-ingest` +- [x] RAG opérationnel — Qdrant ~436 chunks (embeddings nomic-embed-text `:1238`, dim 768), `rag-query` / `rag-ingest` - [x] User `hermes` avec SSH partagé entre storage-01 et gpu-01 - [x] Cluster Kubernetes opérationnel (Talos v1.13 + talhelper) - [x] MetalLB + Traefik + wildcard DNS `lab.local` @@ -259,8 +259,8 @@ Elle est gérée automatiquement par le rôle Ansible `llama_server`. - [x] hermes-auto-improve — analyse quotidienne de la doc par Hermes (n8n 22h → PR `hermes/daily-work`) - [x] Ghostfolio — suivi de portefeuille (`ghostfolio.lab.local`, PostgreSQL s01 + Redis) - [x] STT — assistant vocal « Jarvis » (client `stt` + STT-server in-cluster, mémoire Qdrant `stt-memory`) -- [x] Modèle d'embedding dédié — nomic-embed-text sur gpu-01 `:1238` (utilisé par la mémoire STT) -- [x] Réparer Qdrant — crash-loop résolu 2026-06-17 (collection `funk-docs` supprimée → à re-ingérer) -- [ ] Re-ingérer le RAG (`rag-ingest`) et le basculer sur l'embedding dédié `:1238` +- [x] Modèle d'embedding dédié — nomic-embed-text sur gpu-01 `:1238` (utilisé par la mémoire STT **et le RAG**) +- [x] Réparer Qdrant — crash-loop résolu 2026-06-17 ; collection `funk-docs` **reconstruite** depuis (436 chunks) +- [x] Re-ingérer le RAG (`rag-ingest`) **basculé sur l'embedding dédié `:1238`** (dim 768) - [ ] WOL compute nodes (configuration BIOS) - [ ] Route statique Freebox diff --git a/admin/ia/rag.md b/admin/ia/rag.md index dad6708..7a090a6 100644 --- a/admin/ia/rag.md +++ b/admin/ia/rag.md @@ -1,9 +1,8 @@ # RAG — Documentation Funk -> ⚠️ **À re-ingérer** — Qdrant a été réparé le **2026-06-17** (fin du crash-loop), mais la -> réparation a **supprimé la collection `funk-docs`** : `rag-query` ne retourne rien tant que -> `rag-ingest` n'a pas reconstruit l'index (reconstructible depuis `admin/`). -> Détails de l'incident : `admin/incidents.md` (entrée 2026-06-05). +> ✅ **Opérationnel** (relevé 2026-06-21) — `funk-docs` reconstruite après l'incident Qdrant du +> 2026-06-17 : **436 chunks**, statut 🟢 green, embeddings **nomic-embed-text** (`:1238`, dim 768). +> `rag-query` fonctionne. Détails de l'incident : `admin/incidents.md` (entrée 2026-06-05). Le RAG (Retrieval-Augmented Generation) permet à Hermes de répondre en s'appuyant sur la documentation du repo (`admin/`) plutôt que sur sa seule mémoire de modèle. @@ -17,7 +16,7 @@ Hermes (funk-ai) │ terminal: rag-query "comment relancer dnsmasq ?" ▼ /usr/local/bin/rag-query (storage-01) - │ 1. Embed la question → POST http://192.168.10.20:1234/v1/embeddings + │ 1. Embed la question → POST http://192.168.10.20:1238/v1/embeddings (nomic-embed-text) │ 2. Recherche vectorielle → POST http://127.0.0.1:6333/collections/funk-docs/points/search ▼ Qdrant (storage-01:6333) @@ -40,52 +39,37 @@ Hermes formule sa réponse en citant les sources | `rag-query` | `/usr/local/bin/rag-query` | Interroge Qdrant depuis la ligne de commande | | Skill `rag-docs` | Profil `funk-ai` Hermes | Enseigne à Hermes comment utiliser `rag-query` | | Docs indexées | `/srv/data/rag/docs/` (NVMe) | Copie locale du dossier `admin/` | -| Collection Qdrant | `funk-docs` | supprimée le 2026-06-17 → **à re-ingérer** (≈339 chunks, dim 4096 Cosine) | +| Collection Qdrant | `funk-docs` | **436 chunks**, 🟢 green, **dim 768 Cosine** (nomic-embed-text) | --- ## Modèle d'embedding utilisé -**Qwen3-8B** via llama-server GPU (port 1234), avec les flags `--embeddings --pooling mean`. +**nomic-embed-text** via l'instance dédiée llama-server `llama-embed` sur gpu-01 (`:1238`, **CPU**, +dim 768). C'est un **vrai modèle d'embedding** — les scripts déployés `rag-ingest` et `rag-query` +le hardcodent (`EMBED_URL=http://192.168.10.20:1238/v1/embeddings`, `EMBED_MODEL=nomic-embed-text`). -C'est le modèle de chat principal, réutilisé pour les embeddings. +> Historique : le RAG utilisait au départ **Qwen3-8B** (modèle de chat, `:1234`, dim 4096) réutilisé +> pour les embeddings → scores cosinus saturés (0.90–0.95), peu discriminants. La migration vers +> nomic (dim 768) étale les scores → tri par pertinence réel. La collection a été recréée à dim 768. -### Limitation connue +> ⚠️ **Drift IaC** : `ansible/roles/rag/defaults/main.yml` a longtemps gardé `embed_url: :1234` / +> `embed_model: qwen3-8b` — variables **mortes** (le handler lance `rag-ingest` sans passer d'env → +> le défaut hardcodé nomic du script gagne). Aligné sur nomic dans le même lot que ce relevé. -Qwen3-8B est un modèle génératif, **pas un modèle d'embedding dédié**. -Ses représentations vectorielles ont peu de discrimination sémantique : -les scores de similarité cosinus sont uniformément hauts (0.90–0.95) -quelle que soit la pertinence du résultat. - -Conséquence : les résultats retournés ne sont pas triés par pertinence réelle — -le fichier avec le plus de tokens (ex : `incidents.md`) remonte souvent en premier. - -### Quand améliorer - -Pour une recherche sémantique précise, utiliser un modèle d'embedding dédié : - -| Modèle | Taille | Dimension | Notes | -|---|---|---|---| -| `nomic-embed-text-v1.5` | ~274 MB | 768 | Rapide, bon équilibre qualité/taille | -| `bge-m3` | ~1.2 GB | 1024 | Multilingue (français natif) — meilleur choix pour ce repo | - -Déploiement — **déjà fait pour STT** (instance `nomic-embed-text` sur `:1238`, dim 768) : -le rôle `llama_server` gère désormais une instance dédiée embeddings sur gpu-01 (GPU), -activée par `llama_embed_enabled` (voir `ansible/roles/llama_server/README.md`). STT pointe -dessus (`STT_EMBED_URL=http://192.168.10.20:1238/v1/embeddings`). +L'instance `llama-embed` est gérée par le rôle `llama_server` (`llama_embed_enabled`, voir son README). ```bash # (re)déployer l'instance embeddings sur gpu-01 ansible-playbook -i inventory.yml playbooks/gpu-01.yml --tags llama_server ``` -Pour basculer **le RAG** sur cette même instance (quand il sera réparé) : -```bash -# Modifier ansible/roles/rag/defaults/main.yml : -# embed_url: "http://192.168.10.20:1238/v1/embeddings" -# embed_model: "nomic-embed-text" -# Puis re-indexer (la dimension passe à 768 → collection recréée) : rag-ingest /srv/data/rag/docs/ -``` +### Alternative envisagée + +| Modèle | Taille | Dimension | Notes | +|---|---|---|---| +| `nomic-embed-text` | ~274 MB | 768 | **En service** — rapide, bon équilibre qualité/taille | +| `bge-m3` | ~1.2 GB | 1024 | Multilingue (français natif) — option si la qualité FR doit monter | --- @@ -143,7 +127,7 @@ rsync -av --delete admin/ storage-01:/srv/data/rag/docs/ ssh storage-01 "rag-ingest /srv/data/rag/docs/" ``` -L'ingestion prend ~5-10 minutes pour 339 chunks (embeddings via GPU). +L'ingestion prend quelques minutes pour ~436 chunks (embeddings via l'instance nomic `:1238`, CPU). Elle est idempotente — re-lancer ne crée pas de doublons (IDs stables basés sur MD5 du fichier+section). --- @@ -197,9 +181,8 @@ hermes-skills/funk/rag-docs/ | Sujet | Détail | |---|---| -| Qualité embeddings | Qwen3-8B = modèle chat réutilisé — scores peu discriminants. Fonctionnel mais pas optimal. | -| Modèle dédié | `nomic-embed-text` ou `bge-m3` diviseraient les faux positifs par ~3 | -| Contention GPU | `rag-ingest` sollicite le GPU (port 1234) pendant ~5-10 min — éviter pendant une session d'inférence active | +| Qualité embeddings | `nomic-embed-text` (modèle dédié) — scores cosinus discriminants, tri par pertinence réel | +| Embeddings CPU | `llama-embed` (:1238) tourne en **CPU** (découplé du slot chat GPU) — `rag-ingest` ne contend pas le GPU. ubatch=2048 requis (sinon 500 sur chunks > 512 tokens) | | Re-indexation | Obligatoire après modification de `admin/` — pas de sync automatique | | Qdrant persistance | Données dans `/srv/data/qdrant/` sur NVMe — survivent aux redémarrages | -| Score minimum | `MIN_SCORE = 0.60` dans `rag-query` — tous les résultats sont au-dessus avec ce modèle | +| Score minimum | `MIN_SCORE` dans `rag-query` ajusté pour nomic (scores plus étalés que qwen3-8b) | diff --git a/admin/ia/stt.md b/admin/ia/stt.md index a1bf219..4e1ff93 100644 --- a/admin/ia/stt.md +++ b/admin/ia/stt.md @@ -31,7 +31,7 @@ Objectif ultérieur : « agir sur le homelab » via les outils de Hermes (phase | Agir sur le homelab | Hermes Agent (`:8080`, profils funk-ai/system/monitor/brain) | ✅ opérationnel | | Voix (STT + TTS + wake word) | `tools/hermes-voice/` — faster-whisper + Piper + webrtcvad | ✅ existe (CLI only) | | Démarrage auto au boot | `stt --install-service` (systemd --user) — repris du pattern `tools/hermes-voice/` | ✅ | -| Mémoire sémantique | Qdrant `:6333` + RAG (`rag-query`/`rag-ingest`) sur s01 | ✅ Qdrant réparé 17/06 (RAG `funk-docs` à re-ingérer) | +| Mémoire sémantique | Qdrant `:6333` + RAG (`rag-query`/`rag-ingest`) sur s01 | ✅ Qdrant réparé 17/06, RAG `funk-docs` re-ingéré (436 chunks, nomic dim 768) | Maillon réellement manquant : **l'interface graphique HUD** + le packaging + la mémoire perso. @@ -125,7 +125,7 @@ au prompt système (`STT_DISABLE_THINKING`, défaut `true` ; inoffensif hors Qwe borné `max_turns` + TTL) et l'injecte dans l'appel LLM. `/v1/ask {session_id}` + `/v1/reset`. Le client génère un `session_id` par run. Deployment en **1 worker** (cohérence mémoire process). - **Long-terme (5b, ✅ validé 17/06)** : collection Qdrant dédiée `stt-memory` (indépendante du - `funk-docs` du RAG), embeddings via Qwen3 `:1234` (dim 4096, Cosine), souvenirs pertinents + `funk-docs` du RAG), embeddings via nomic-embed-text `:1238` (dim 768, Cosine), souvenirs pertinents (top-k) injectés au prompt. Qdrant en IP directe `192.168.10.1:6333`. **Dégrade proprement** si Qdrant/embeddings injoignables (la mémoire court-terme tient). - **Validé bout-en-bout** : « mon chat s'appelle Felix » (session A) rappelé dans une diff --git a/admin/incidents.md b/admin/incidents.md index 8b94ff9..0b59b7b 100644 --- a/admin/incidents.md +++ b/admin/incidents.md @@ -23,7 +23,7 @@ error: unexpected character 'D' while parsing minor version number Le fichier `version.info` du segment contient `0.D\0` au lieu d'un numéro de version — corruption de données (première occurrence le 2026-06-05 à 21h10). -### Résolution (crash-loop résolu le 2026-06-17 ; re-ingest encore à faire) +### Résolution (crash-loop résolu le 2026-06-17 ; RAG re-ingéré le 2026-06-21) La collection `funk-docs` est entièrement reconstructible depuis `admin/` : @@ -37,9 +37,10 @@ curl -s http://127.0.0.1:6333/collections # doit répondre > **État au 2026-06-17** : les 3 premières étapes (stop + drop `funk-docs` + start) ont été > appliquées sur s01 pour sortir Qdrant du crash-loop (cf. `admin/ia/stt.md`, jalon 5c). Le -> service Qdrant et la mémoire STT (`stt-memory`) sont donc opérationnels, **mais** `rag-ingest` -> n'a pas encore été relancé : la collection `funk-docs` est vide → `rag-query` reste muet -> tant que l'index n'est pas reconstruit. +> service Qdrant et la mémoire STT (`stt-memory`) sont opérationnels. +> +> ✅ **Clôturé (2026-06-21)** : `funk-docs` a été **reconstruite** via `rag-ingest` (relevé : 436 +> chunks, 🟢 green, embeddings nomic-embed-text `:1238` dim 768) → `rag-query` opérationnel. ### Prévention @@ -52,7 +53,7 @@ curl -s http://127.0.0.1:6333/collections # doit répondre | Date | Composant | Résumé | Sévérité | |---|---|---|---| | 2026-06-19 | llama-server (gpu-01) | Inférence gelée (`/health` OK, génération bloquée) → 502 LLM — **résolu** par restart. Détail : [`incidents-llm-gpu.md`](incidents-llm-gpu.md) | Important | -| 2026-06-05 | Qdrant | **Résolu 2026-06-17** — crash-loop corrigé (drop `funk-docs`) ; RAG à re-ingérer | Important | +| 2026-06-05 | Qdrant | **Résolu 2026-06-17**, RAG **re-ingéré 2026-06-21** (436 chunks, nomic dim 768) | Important | | 2026-05-29 | RAID5 / sdb + storage-01 | sdb ATA bus errors sous I/O — migration /srv/data du RAID vers NVMe | Important | | 2026-05-27 | RAID5 / sdd | Disque sdd défaillant (44 secteurs morts) — corruptions multiples en cascade | Critique | | 2026-05-14 | Grafana | OOMKilled — limite 256Mi trop serrée pour Grafana 13 | Warning | diff --git a/admin/install/README.md b/admin/install/README.md index ea82722..25ddada 100644 --- a/admin/install/README.md +++ b/admin/install/README.md @@ -5,9 +5,9 @@ Chaque fichier couvre une machine ou une couche du projet de A à Z. | Guide | Machine | OS | Rôle | |---|---|---|---| -| [storage-01.md](storage-01.md) | storage-01 | AlmaLinux 9.7 | Passerelle + RAID5 + services IA (Hermes, LiteLLM, Qdrant, PostgreSQL) | -| [gpu-01.md](gpu-01.md) | gpu-01 | AlmaLinux 9.7 | Inférence LLM (ROCm + llama-server, RX 6700XT) | -| [kubernetes.md](kubernetes.md) | compute-01/02/03 | Talos v1.13 | Cluster Kubernetes (MetalLB, Traefik, DNS wildcard) | +| [storage-01.md](storage-01.md) | storage-01 | AlmaLinux 9.8 (ISO 9.7) | Passerelle + RAID5 + services IA (Hermes, LiteLLM, Qdrant, PostgreSQL) | +| [gpu-01.md](gpu-01.md) | gpu-01 | AlmaLinux 9.8 (ISO 9.7) | Inférence LLM (ROCm + llama-server, RX 6700XT) | +| [kubernetes.md](kubernetes.md) | compute-01/02/03 | Talos v1.13 (k8s v1.33.1) | Cluster Kubernetes (MetalLB, Traefik, DNS wildcard) | ## Ordre d'installation recommandé diff --git a/admin/install/gpu-01.md b/admin/install/gpu-01.md index a1949ca..507edae 100644 --- a/admin/install/gpu-01.md +++ b/admin/install/gpu-01.md @@ -37,7 +37,7 @@ Il est consommé par storage-01 (LiteLLM le pointe directement via HTTP). | CPU | AMD Ryzen 5 3600 (6c/12t) | | RAM | 32 GB DDR4 | | GPU | AMD RX 6700XT — 12 GB VRAM, architecture RDNA2 (gfx1031) | -| OS | AlmaLinux 9.7 | +| OS | AlmaLinux 9.8 (installé depuis ISO 9.7, point releases via `dnf update`) | | Disque | SSD SATA 500 GB (OS + binaires) | | Stockage modèles | NFS via storage-01 `/srv/data/models` → monté sur `/mnt/models` | diff --git a/admin/k8s/k9s.md b/admin/k8s/k9s.md index 0917890..ed953ac 100644 --- a/admin/k8s/k9s.md +++ b/admin/k8s/k9s.md @@ -74,9 +74,12 @@ ssh -t storage-01 k9s # -t obligatoire pour allouer un TTY (TUI) | Namespace | Contenu | |---|---| | `monitoring` | Prometheus, Grafana, AlertManager | -| `ai` | Open WebUI, n8n | -| `infra` | Traefik, MetalLB, NFS provisioner | +| `ai` | Open WebUI, n8n, **STT-server**, **Ghostfolio** (+ Redis) | +| `infra` | Traefik, MetalLB, NFS provisioner, **registry** in-cluster | | `argocd` | ArgoCD (GitOps) | +| `metallb-system` | MetalLB (controller + speakers) | +| `nfs-provisioner` | nfs-subdir-external-provisioner | +| `sacrifice` | Jeu FPS Sacrifice (web + CronJob) — **hors repo Funk-lab, hors ArgoCD** | | `kube-system` | Composants Kubernetes internes | --- diff --git a/admin/k8s/talos.md b/admin/k8s/talos.md index 65c83bd..395065e 100644 --- a/admin/k8s/talos.md +++ b/admin/k8s/talos.md @@ -10,7 +10,7 @@ Le cluster Kubernetes **funk** compte **3 nœuds** (trois machines ThinkCentre), sous **Talos Linux v1.13.0** (Kubernetes v1.33.1) : **compute-01** est le control-plane, **compute-02** et **compute-03** sont des workers. Les deux autres machines du homelab — **storage-01** (passerelle) et **gpu-01** (llama-server) — sont **hors du cluster** et -tournent sous **AlmaLinux 9.7**. Donc : 3 nœuds Kubernetes Talos + 2 hôtes AlmaLinux hors cluster. +tournent sous **AlmaLinux 9.8**. Donc : 3 nœuds Kubernetes Talos + 2 hôtes AlmaLinux hors cluster. | Nœud | IP | Rôle | Disque | RAM | |---|---|---|---|---| diff --git a/admin/ops/etat-cluster.md b/admin/ops/etat-cluster.md new file mode 100644 index 0000000..8fa6b7f --- /dev/null +++ b/admin/ops/etat-cluster.md @@ -0,0 +1,167 @@ +# État réel du cluster Funk — snapshot vérifié + +> Relevé **2026-06-21** directement sur les machines (SSH s01/g01 + `kubectl`). Ce document +> reflète l'état **observé**, pas l'état *souhaité* de l'IaC — en cas d'écart, les écarts connus +> sont signalés (⚠️). Pour la procédure de relevé, voir la fin du fichier. + +--- + +## Machines + +| Machine | IP | OS / kernel | Uptime relevé | Rôle | +|---|---|---|---|---| +| storage-01 | 192.168.10.1 (LAN) / 192.168.1.200 (WAN) | AlmaLinux **9.8** (Olive Jaguar), `5.14.0-687.5.3.el9_8` | 20 j | Passerelle + bastion + données + IA hors-cluster | +| gpu-01 | 192.168.10.20 | AlmaLinux **9.8**, `5.14.0-687.5.3.el9_8` | — | llama-server (RX 6700XT, ROCm 7.x) hors-cluster | +| compute-01 | 192.168.10.11 | Talos v1.13 / **k8s v1.33.1** | 40 j | k8s control-plane | +| compute-02 | 192.168.10.12 | Talos v1.13 / **k8s v1.33.1** | 40 j | k8s worker | +| compute-03 | 192.168.10.13 | Talos v1.13 / **k8s v1.33.1** | 40 j | k8s worker | + +> ⚠️ `CLAUDE.md` indiquait AlmaLinux **9.7** pour s01/g01 — la réalité est **9.8**. + +--- + +## storage-01 — services actifs (systemd) + +| Service | Port(s) écoute | Rôle | +|---|---|---| +| `litellm` | `0.0.0.0:4000` | Proxy multi-modèles (Hermes + ask-agent + STT-server) | +| `llm-heartbeat` | — | **Anti-502** : garde chaud le tuyau LiteLLM↔llama-server (rôle `litellm`) | +| `hermes-agent` | (pas de port WAN) | Agent Hermes — appli **TUI**, **pas d'API HTTP** (le « gateway :8080 » de la doc historique n'écoute pas) | +| `hermes-auto-improve` | `0.0.0.0:9095` | Trigger HTTP analyse doc quotidienne | +| `hermes-exec` | `0.0.0.0:9096` | Exécuteur d'actions vocales `hermes -z --yolo` (jeton Bearer) — assistant STT | +| `qdrant` | `0.0.0.0:6333` / `:6334` | Base vectorielle (RAG `funk-docs` + mémoire STT `stt-memory`) | +| `postgresql-16` | `192.168.10.1:5432` | PostgreSQL 16 (8 bases, cf. plus bas) | +| `dnsmasq` | `192.168.10.1:53` | DNS + wildcard `*.lab.local` | +| `nfs-*` (mountd/idmapd/statd) | `:2049 :111 :20048` | Export NFS modèles + PVCs k8s | +| `node_exporter` | `:9100` | Métriques Prometheus | +| `alertmanager-webhook` | `0.0.0.0:9093` | Pont AlertManager → Hermes monitor | +| `postfix` | `:25` | Relais SMTP sortant (Gmail App Password) | + +> Note : `:9093` côté s01 = **alertmanager-webhook** (storage-01), à ne pas confondre avec +> l'Alertmanager k8s (`alertmanager.lab.local`, in-cluster). + +--- + +## gpu-01 — services llama-server (systemd) + +| Service | Port | État relevé | Rôle | +|---|---|---|---| +| `llama-server` | `:1234` | ✅ actif | Chat principal **qwen3-8b** (GPU, ROCm) | +| `llama-embed` | `:1238` | ✅ actif | Embeddings dédiés **nomic-embed-text** (**CPU**, dim 768, `--ubatch-size 2048`) | +| `llama-embed-heartbeat` | — | ✅ actif | Garde chaud le slot embeddings :1238 | +| `llama-watchdog` | — | ✅ actif | **Auto-réparation** du llama-server figé (bug ROCm gfx1031) | +| llama-server CPU `:1236` | `:1236` | ⚠️ **éteint** | Instance manuelle (profil Hermes `system`) — **non gérée par IaC** | +| llama-server CPU `:1237` | `:1237` | ⚠️ **éteint** | Instance manuelle (profil Hermes `monitor`) — **non gérée par IaC** | + +> ⚠️ Au relevé, **seuls `:1234` et `:1238` écoutent**. Les instances CPU `:1236`/`:1237` sont +> **arrêtées** → les profils Hermes `system` et `monitor` (qui pointent dessus) sont actuellement +> **dégradés**. Ce sont des services manuels (gap IaC connu, cf. `ansible/roles/llama_server/README.md`). +> +> ⚠️ GPU : `rocminfo` rapporte `gfx1030` (et non `gfx1031`) — c'est l'effet attendu de +> `HSA_OVERRIDE_GFX_VERSION=10.3.0`, indispensable car la RX 6700XT (gfx1031) n'est pas +> officiellement supportée par ROCm. + +--- + +## LiteLLM — modèles exposés (`:4000`) + +| Alias | Backend | +|---|---| +| `hermes-default` | Alias consommé par Hermes (bascule via `hermes-switch`) | +| `qwen3-8b` | llama-server GPU gpu-01 `:1234` | +| `claude-sonnet-4-6` | API Anthropic (profil `brain`, facturé) | +| `claude-opus-4-7` | API Anthropic (facturé) | + +--- + +## Cluster k8s — workloads + +**Nœuds** : compute-01/02/03 tous `Ready`, k8s `v1.33.1` (40 j d'uptime). + +**Namespaces & pods** (tous `Running` au relevé) : + +| Namespace | Workloads | +|---|---| +| `ai` | ghostfolio, ghostfolio-redis, n8n, open-webui, **stt-server** | +| `argocd` | application-controller, applicationset, notifications, redis, repo-server, server | +| `infra` | **traefik** (LB `192.168.10.200`), **registry** (registry Docker in-cluster) | +| `monitoring` | kube-prometheus-stack (Prometheus, Alertmanager, Grafana **13.0.1**, kube-state-metrics, operator, node-exporters) | +| `metallb-system` | controller + speakers | +| `nfs-provisioner` | nfs-subdir-external-provisioner | +| `kube-system` | coredns, flannel, kube-proxy, control-plane statiques | +| **`sacrifice`** | **`sacrifice-web`** (`sacrifice.lab.local`) + CronJob `sacrifice-assign-renfort` | + +> ⚠️ **Namespace `sacrifice` non documenté** dans `CLAUDE.md`. C'est le projet de jeu FPS +> [Sacrifice](https://github.com/Alkatrazz24/Sacrifice) (monorepo séparé). Déployé **hors du repo +> Funk-lab** et **hors ArgoCD** (absent de la liste des Applications) — sa propre chaîne le pousse. +> Il possède aussi sa base PostgreSQL `sacrifice` sur storage-01. + +**ArgoCD Applications** (toutes `Synced` / `Healthy`) : +`root` · `ghostfolio` · `n8n` · `open-webui` · `stt` · `monitoring` · `kube-prometheus-stack` · +`nfs-provisioner` · `nfs-subdir-external-provisioner`. + +**Exposition HTTP** : + +| Type | Hôtes | +|---|---| +| `Ingress` standard | `argocd.lab.local`, `grafana.lab.local`, `prometheus.lab.local`, `alertmanager.lab.local`, `sacrifice.lab.local` | +| `IngressRoute` (CRD Traefik) | `ai/open-webui`, `ai/n8n`, `ai/ghostfolio`, `ai/stt-server`, `infra/traefik-dashboard` | + +> Les services du namespace `ai` (openwebui, n8n, ghostfolio, stt) passent par des **IngressRoute +> Traefik** (CRD), pas par des `Ingress` standards. + +--- + +## PostgreSQL 16 (storage-01) — bases + +`hermes` · `litellm` · `n8n` · `openwebui` · `ghostfolio` · `grafana` · `sacrifice` · `postgres` + +> ⚠️ Bases non listées dans `CLAUDE.md` : **`grafana`** (Grafana k8s utilise un PG externe sur s01) +> et **`sacrifice`** (projet hors-repo). + +--- + +## RAG / Qdrant — état + +| Collection | Points | Statut | Dim / distance | +|---|---|---|---| +| `funk-docs` | **436** | 🟢 green | 768 / Cosine | +| `stt-memory` | — | 🟢 | 768 / Cosine | + +> ✅ **`funk-docs` reconstruite et complète (436 chunks, 0 erreur)** — le warning « collection +> supprimée le 2026-06-17, re-ingest requis » de `CLAUDE.md`/`README`/`admin/ia/rag.md` est +> **périmé**. Embeddings via **nomic-embed-text** (`:1238`, dim 768), **plus** qwen3-8b. +> +> 🐛 **Fix de ce lot — embeddings tronqués à 512 tokens** : le relevé initial montrait 389 points +> avec **~46 chunks manquants** (HTTP 500 `input too large to process. increase the physical batch +> size (current: 512)`). Cause : `llama-embed` (:1238) tournait avec l'**ubatch llama.cpp par +> défaut (512)**, or en mode `--embeddings`+pooling toute l'entrée doit tenir dans un seul ubatch +> → tout chunk > 512 tokens échouait (CHUNK_MAX=2000 chars ≈ 700 tokens). **Corrigé** : `--batch-size` +> /`--ubatch-size = 2048` (= ctx) → ré-ingestion **436/436, 0 erreur**. Fix durable dans le rôle +> `llama_server` (`llama_embed_ubatch_size`) ; appliqué en live via drop-in systemd sur g01 (à +> réconcilier au prochain `make apply-gpu`). `rag-ingest` gagne aussi un retry sur 5xx transitoires. +> +> ⚠️ Drift IaC mineur (corrigé) : `ansible/roles/rag/defaults/main.yml` mentionnait encore +> `embed_url: :1234` / `embed_model: qwen3-8b` (variables **mortes** — les scripts déployés +> hardcodent nomic `:1238`). + +--- + +## Comment régénérer ce snapshot + +Depuis le poste perso (accès `ssh storage-01` = user `ansible` ; g01 via `root@192.168.10.20` ; +kubeconfig `/home/ansible/.kube/config` sur s01) : + +```bash +# Services + ports s01 +ssh storage-01 'systemctl list-units --type=service --state=running | grep -iE "litellm|hermes|qdrant|postgres|nfs|dnsmasq|node_exporter|alertmanager|postfix"; ss -tlnp' +# gpu-01 +ssh storage-01 'ssh root@192.168.10.20 "systemctl list-units llama* ; ss -tlnp | grep :12"' +# k8s +ssh storage-01 'KUBECONFIG=/home/ansible/.kube/config kubectl get nodes,pods,ingress,ingressroute -A' +ssh storage-01 'KUBECONFIG=/home/ansible/.kube/config kubectl get applications -n argocd' +# Bases PG + Qdrant + LiteLLM +ssh storage-01 'sudo -u postgres psql -tAc "SELECT datname FROM pg_database WHERE datistemplate=false"' +ssh storage-01 'curl -s localhost:6333/collections | python3 -m json.tool' +ssh storage-01 'curl -s localhost:4000/v1/models -H "Authorization: Bearer lm-studio" | python3 -m json.tool' +``` diff --git a/ansible/roles/llama_server/defaults/main.yml b/ansible/roles/llama_server/defaults/main.yml index 0c8d583..c2a0688 100644 --- a/ansible/roles/llama_server/defaults/main.yml +++ b/ansible/roles/llama_server/defaults/main.yml @@ -23,6 +23,11 @@ llama_embed_model_path: "" # chemin GGUF sur /mnt/models (NFS) llama_embed_model_url: "" # URL de téléchargement (HuggingFace) — get_url si absent llama_embed_model_alias: "nomic-embed-text" llama_embed_ctx_size: 2048 +# Batch physique (ubatch) = contexte : en mode --embeddings avec pooling, toute l'entrée doit +# tenir dans UN seul ubatch. Le défaut llama.cpp (512) fait échouer en HTTP 500 tout chunk +# > 512 tokens (« input too large to process. increase the physical batch size ») — c'est ce +# qui faisait rater ~46 chunks du RAG (CHUNK_MAX=2000 chars ≈ 700 tokens). Aligné sur ctx-size. +llama_embed_ubatch_size: 2048 # CPU par défaut (0 couche GPU). nomic-embed-text est minuscule (137M) → ~100 ms en CPU, # DÉTERMINISTE. Sur GPU (99) il partage la RX 6700XT avec le chat qwen3-8b (:1234) et tombe # dans la file derrière une génération → latence BIMODALE (16 ms ou 9-12 s, voire timeout) → diff --git a/ansible/roles/llama_server/templates/llama-embed.service.j2 b/ansible/roles/llama_server/templates/llama-embed.service.j2 index 5bbf7a5..dd93932 100644 --- a/ansible/roles/llama_server/templates/llama-embed.service.j2 +++ b/ansible/roles/llama_server/templates/llama-embed.service.j2 @@ -13,6 +13,8 @@ ExecStart=/opt/llama.cpp/build/bin/llama-server \ --host {{ llama_server_host }} \ --port {{ llama_embed_port }} \ --ctx-size {{ llama_embed_ctx_size }} \ + --batch-size {{ llama_embed_ubatch_size }} \ + --ubatch-size {{ llama_embed_ubatch_size }} \ --n-gpu-layers {{ llama_embed_n_gpu_layers }} \ --alias {{ llama_embed_model_alias }} \ --embeddings \ diff --git a/ansible/roles/rag/defaults/main.yml b/ansible/roles/rag/defaults/main.yml index c89b513..947fbcf 100644 --- a/ansible/roles/rag/defaults/main.yml +++ b/ansible/roles/rag/defaults/main.yml @@ -3,6 +3,10 @@ rag_data_dir: /srv/data/rag rag_docs_dir: /srv/data/rag/docs qdrant_url: "http://127.0.0.1:6333" -embed_url: "http://192.168.10.20:1234/v1/embeddings" -embed_model: "qwen3-8b" +# Embeddings : instance dédiée nomic-embed-text (gpu-01 :1238, dim 768), pas le modèle de chat. +# NB : ces deux vars ne sont PAS injectées dans les scripts (le handler lance rag-ingest sans env) — +# les scripts files/rag-ingest et files/rag-query hardcodent ces mêmes valeurs par défaut. +# Conservées ici pour documenter la cible et éviter toute régression vers qwen3-8b/:1234. +embed_url: "http://192.168.10.20:1238/v1/embeddings" +embed_model: "nomic-embed-text" rag_collection: "funk-docs" diff --git a/ansible/roles/rag/files/rag-ingest b/ansible/roles/rag/files/rag-ingest index f01e4c3..42db8b3 100644 --- a/ansible/roles/rag/files/rag-ingest +++ b/ansible/roles/rag/files/rag-ingest @@ -7,6 +7,7 @@ Usage: rag-ingest [docs_dir] import os import sys import json +import time import hashlib import re import urllib.request @@ -57,8 +58,22 @@ def ensure_collection(): def embed(text): - result = _request("POST", EMBED_URL, {"model": EMBED_MODEL, "input": text}) - return result["data"][0]["embedding"] + # L'instance llama-embed (:1238) renvoie occasionnellement des 500 transitoires sous charge + # soutenue (slot saturé) → retry avec backoff. Les chunks sont bornés (CHUNK_MAX=2000) donc + # un 500 n'est pas dû à un dépassement de contexte. + last = None + for attempt in range(5): + try: + result = _request("POST", EMBED_URL, {"model": EMBED_MODEL, "input": text}) + return result["data"][0]["embedding"] + except (urllib.error.HTTPError, urllib.error.URLError) as e: + last = e + code = getattr(e, "code", None) + # Ne réessaie que sur erreurs transitoires (5xx) ou réseau + if code is not None and code < 500: + raise + time.sleep(0.5 * (attempt + 1)) + raise last def chunk_markdown(rel_path, content): diff --git a/progress/2026-06-21.md b/progress/2026-06-21.md index 5fb4d4a..dee800d 100644 --- a/progress/2026-06-21.md +++ b/progress/2026-06-21.md @@ -85,6 +85,29 @@ Bascule du client sur `asr_engine = "onnx"` (NVIDIA Parakeet `nemo-parakeet-tdt- --- +## Relevé d'état réel + RAG re-ingéré (soir) + +Passe de **vérification terrain** (SSH s01/g01 + `kubectl`) pour aligner la doc sur la réalité, et +**re-ingestion du RAG**. Nouveau doc de référence : **`admin/ops/etat-cluster.md`** (snapshot daté). + +Écarts doc↔réalité corrigés (CLAUDE.md, README, install, k8s, incidents, rag, stt) : +- OS **AlmaLinux 9.8** (et non 9.7) sur s01/g01 ; **k8s v1.33.1** sur les compute nodes. +- RAG `funk-docs` **n'était pas vide** : le warning « supprimée 2026-06-17, re-ingest requis » était + périmé. Embeddings basculés sur **nomic-embed-text** (`:1238`, dim 768, **CPU**) — plus qwen3-8b. +- Namespace **`sacrifice`** (jeu FPS, hors-repo & hors ArgoCD) + base PG `sacrifice` + `grafana` + non documentés ; services `ai` exposés via **IngressRoute** Traefik ; registry in-cluster. +- Services de résilience non mentionnés : `llm-heartbeat` (s01), `llama-watchdog`/`llama-embed(-heartbeat)` (g01). +- Instances llama CPU `:1236`/`:1237` (profils `system`/`monitor`) **manuelles et éteintes** au relevé. + +🐛 **Bug RAG trouvé & corrigé** : ~46 chunks rataient l'embedding (HTTP 500 *input too large… increase +physical batch size: 512*). `llama-embed` tournait avec l'**ubatch llama.cpp par défaut (512)** ; en +mode `--embeddings`+pooling l'entrée doit tenir dans un seul ubatch → chunks > 512 tokens KO. **Fix** : +`--batch-size`/`--ubatch-size = 2048` (rôle `llama_server`, var `llama_embed_ubatch_size` ; appliqué +en live via drop-in systemd g01). `rag-ingest` gagne un retry 5xx. Drift IaC nettoyé (`rag/defaults` +pointait encore qwen3-8b `:1234`). **Résultat : ré-ingestion 436/436, 0 erreur, collection 🟢.** + +--- + ## Versions - Client `stt` : `0.7.0 → 0.13.0` (portail, contrôles, santé, contextes, intents, version, unification). @@ -94,7 +117,10 @@ Bascule du client sur `asr_engine = "onnx"` (NVIDIA Parakeet `nemo-parakeet-tdt- ## Prochaines étapes -- **Merger #43** → activer les actions ; faire le 1er test vocal avec confirmation (HUD → 🤖 Agent). +- ✅ **#43 mergé** (actions activées) et **RAG re-ingéré** (436 chunks) — faits. +- **Appliquer `make apply-gpu`** pour réconcilier le drop-in `llama-embed` (ubatch) dans l'IaC, puis + supprimer `/etc/systemd/system/llama-embed.service.d/batch.conf` sur g01. +- 1er test vocal d'action avec confirmation (HUD → 🤖 Agent). - Optionnel : ajouter le jeton Ghostfolio en config client si l'intent « combien » est souhaité hors contexte. - Streaming ASR (transcription partielle live dans le HUD). - Corriger le wake word (« Asa » vs « Hermès ») si désiré.