From 1340c36b1600efcc6c7ae345f3dff77cd316e100 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 20:31:13 +0000 Subject: [PATCH] docs(stt): documenter le fix /no_think Qwen3 + instance embeddings :1238 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - admin/ia/stt.md : caveat « thinking » Qwen3 (content vide / timeout 502) + fix /no_think + fallback reasoning_content ; roadmap 5e ; bannière. - stt/server/README.md : env STT_DISABLE_THINKING + section caveat Qwen3. - admin/ia/llama_server.md : 4e instance llama-embed :1238 (nomic, dim 768), double source d'embeddings (1234 Qwen3 / 1238 nomic), caveat thinking, correction dim Qwen3 (3584 → 4096). - admin/ia/litellm.md : cross-ref caveat thinking (concerne tous les consommateurs de hermes-default/qwen3). - ci : exclure **/*.md du trigger build-stt-server (doc-only ne rebuild plus). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013FmcxGsyXZXogiAHQLjnZT --- .github/workflows/build-stt-server.yml | 1 + admin/ia/litellm.md | 5 ++++ admin/ia/llama_server.md | 37 +++++++++++++++++++++++--- admin/ia/stt.md | 16 ++++++++--- stt/server/README.md | 10 +++++++ 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-stt-server.yml b/.github/workflows/build-stt-server.yml index e0dca87..b0dbd43 100644 --- a/.github/workflows/build-stt-server.yml +++ b/.github/workflows/build-stt-server.yml @@ -7,6 +7,7 @@ on: branches: ["main", "claude/**"] paths: - "stt/server/**" + - "!stt/server/**/*.md" # les changements doc-only ne rebuildent pas l'image - ".github/workflows/build-stt-server.yml" workflow_dispatch: diff --git a/admin/ia/litellm.md b/admin/ia/litellm.md index 3958ef4..73c7263 100644 --- a/admin/ia/litellm.md +++ b/admin/ia/litellm.md @@ -48,6 +48,11 @@ sudo journalctl -u litellm -n 50 > `qwen3-1.7b-system` et `qwen3-1.7b-monitor` sont utilisés par `ask-agent system` et > `ask-agent monitor` — voir [hermes.md](hermes.md). +> ⚠️ **Qwen3 = modèle « thinking »** : il raisonne avant de répondre. Avec un `max_tokens` +> faible, il peut renvoyer un `content` **vide** (budget épuisé en `reasoning_content`) ou +> dépasser le timeout (réflexion longue). Ajouter **`/no_think`** au prompt système pour le +> désactiver (STT le fait via `STT_DISABLE_THINKING`). Voir `admin/ia/llama_server.md`. + --- ## Switch rapide avec hermes-switch diff --git a/admin/ia/llama_server.md b/admin/ia/llama_server.md index 2875ce9..9c7b275 100644 --- a/admin/ia/llama_server.md +++ b/admin/ia/llama_server.md @@ -1,21 +1,27 @@ # llama-server — Inférence LLM (gpu-01) -llama-server (llama.cpp compilé with ROCm 7.x) tourne en **trois instances systemd** sur **gpu-01** (`192.168.10.20`). +llama-server (llama.cpp compilé with ROCm 7.x) tourne en **quatre instances systemd** sur **gpu-01** (`192.168.10.20`). API 100% compatible OpenAI — remplace LM Studio pour l'inférence. --- -## Trois instances +## Quatre instances | Service systemd | Port | Modèle | Backend | Usage | |---|---|---|---|---| | `llama-server` | 1234 | Qwen3-8B Q4_K_M | GPU (RX 6700XT) | Inférence principale — Hermes + LiteLLM | | `llama-server-system` | 1236 | Qwen3-1.7B Q4_K_M | CPU | Profil Hermes `system` (tâches légères) | | `llama-server-monitor` | 1237 | Qwen3-1.7B Q4_K_M | CPU | Profil Hermes `monitor` (supervision) | +| `llama-embed` | 1238 | nomic-embed-text-v1.5 f16 | GPU | Embeddings dédiés (mémoire STT, dim 768) | Les instances CPU (`system`, `monitor`) partagent le même binaire mais des configs distinctes. Les modèles sont sur NFS monté depuis storage-01 (`/mnt/models`). +> `llama-embed` (`:1238`) est **géré par Ansible** (rôle `llama_server`, `llama_embed_enabled`) — +> contrairement aux instances CPU (gap IaC, voir plus bas). Sert un modèle d'embedding **dédié** +> (`nomic-embed-text`, dim 768), bien plus discriminant que Qwen3-8B réutilisé. Partage le GPU +> avec `:1234` (~300 Mo VRAM). + --- ## Service systemd @@ -35,6 +41,11 @@ sudo journalctl -u llama-server-system -f sudo systemctl status llama-server-monitor sudo systemctl restart llama-server-monitor sudo journalctl -u llama-server-monitor -f + +# Instance GPU — embeddings dédiés (nomic-embed-text :1238) +sudo systemctl status llama-embed +sudo systemctl restart llama-embed +sudo journalctl -u llama-embed -f ``` --- @@ -67,12 +78,29 @@ llama-server expose `/v1/embeddings` avec `--embeddings --pooling mean`. Le flag `--pooling mean` est obligatoire pour les LLM causaux (sinon : erreur 400 `Pooling type 'none' is not OAI compatible`). +**Deux sources d'embeddings :** + +| Endpoint | Modèle | Dim | Usage | +|---|---|---|---| +| `:1234/v1/embeddings` | Qwen3-8B (chat réutilisé) | 4096 | RAG (`funk-docs`) — peu discriminant | +| `:1238/v1/embeddings` | nomic-embed-text (dédié) | 768 | Mémoire STT (`stt-memory`) — précis | + +> Qwen3-8B n'est **pas** un modèle d'embedding dédié (cosinus uniformément hauts → recherche +> peu discriminante). L'instance `llama-embed` (`:1238`) sert `nomic-embed-text`, spécialisé. +> Le RAG pourra y basculer quand il sera réparé (voir `admin/ia/rag.md`). + ```bash -# Test embeddings depuis storage-01 +# Test embeddings dédiés nomic (:1238) — depuis le LAN cluster +curl -s -X POST http://192.168.10.20:1238/v1/embeddings \ + -H "Content-Type: application/json" \ + -d '{"model":"nomic-embed-text","input":["test"]}' | jq '.data[0].embedding | length' +# → 768 (dimension nomic-embed-text-v1.5) + +# Test embeddings Qwen3 (:1234) — RAG curl -s -X POST http://192.168.10.20:1234/v1/embeddings \ -H "Content-Type: application/json" \ -d '{"model":"qwen3-8b","input":["test"]}' | jq '.data[0].embedding | length' -# → 3584 (dimension Qwen3-8B) +# → 4096 (dimension Qwen3-8B) ``` --- @@ -197,6 +225,7 @@ Conséquence : un `make apply-gpu` complet sur un hôte vierge ne déploierait P | --metrics obligatoire | Sans ce flag, `/metrics` retourne `501 Not Implemented` — Prometheus ne scrappe rien | | parallel=1 obligatoire | `--parallel 4` divise le ctx en slots → contexte insuffisant pour Hermes | | pooling mean obligatoire | Sans `--pooling mean`, l'endpoint `/v1/embeddings` retourne erreur 400 | +| Qwen3 = modèle « thinking » | Par défaut Qwen3 raisonne avant de répondre → consomme le budget `max_tokens` en `reasoning_content` (`content` vide) ou réfléchit longtemps (timeout). Ajouter **`/no_think`** au prompt système pour le désactiver. STT le fait (`STT_DISABLE_THINKING`) ; à considérer pour tout consommateur de Qwen3 à `max_tokens` faible (ask-agent, profils Hermes). | | Gemma 4 interdit | Crash ROCm sur prompts >800 tokens | | Modèles sur NFS | `/mnt/models` monté depuis storage-01 (NFS) — si NFS down, les 3 services échouent au démarrage | | 3 services indépendants | Chaque instance a son propre service systemd — redémarrer l'un n'affecte pas les autres | diff --git a/admin/ia/stt.md b/admin/ia/stt.md index 3a1f3e8..a4d07dd 100644 --- a/admin/ia/stt.md +++ b/admin/ia/stt.md @@ -10,8 +10,9 @@ Objectif ultérieur : « agir sur le homelab » via les outils de Hermes (phase > technique (FRIDAY, etc.) — c'est juste un identifiant de répertoire/commande. > ✅ **2026-06-17** — déployé in-cluster (ArgoCD), mémoire court-terme (5a) + long-terme (5b) -> **validées sur cible** (rappel cross-session OK via `/v1/memory/health`). Reste : test audio -> bout-en-bout sur le poste (phase 1), HUD avancé (4), auto-start (6), outils Hermes (7). +> **validées sur cible**, embeddings dédiés nomic `:1238` (5d) + fix thinking Qwen3 `/no_think` +> (5e). Reste : test audio bout-en-bout sur le poste (phase 1), HUD avancé (4), auto-start (6), +> outils Hermes (7). --- @@ -82,6 +83,14 @@ switch global type `hermes-switch` (pas de restart, chaque client choisit le sie `GET /v1/models` liste le défaut + les alias autorisés. Noms courts client : `hermes` (=hermes-default), `qwen`, `claude` (=claude-sonnet-4-6), `opus`. +**Caveat Qwen3 — mode « thinking » (corrigé)** : Qwen3 est un modèle de raisonnement. Sans +précaution, il dépense tout le budget `max_tokens` (200) dans `reasoning_content` → `content` +**vide**, ou réfléchit trop longtemps → **timeout 502** (`upstream LiteLLM : ` au message vide — +signature d'un timeout httpx). Diagnostiqué via appel direct LiteLLM : réponse en 0.87s mais +`content=""` et tout dans `reasoning_content`. **Fix** : `brain.py` ajoute le token `/no_think` +au prompt système (`STT_DISABLE_THINKING`, défaut `true` ; inoffensif hors Qwen) et récupère +`reasoning_content` en filet de sécurité si `content` est vide. Caveat partagé : `admin/ia/llama_server.md`. + ### La mémoire — côté serveur - **Court-terme (5a, fait)** : le serveur garde l'historique par `session_id` (en mémoire, @@ -155,9 +164,10 @@ Côté client, pilotable depuis `stt/client/config/` + l'écran de réglages du | **3 — Déploiement cluster** | image ghcr + manifests k8s + ArgoCD (LiteLLM en IP directe) | ✅ déployé | | **4 — HUD avancé** | visualiseur arc-reactor + thèmes + écran réglages | ⏳ | | **5a — Mémoire court-terme** | historique de session côté serveur | ✅ | -| **5b — Mémoire long-terme** | Qdrant `stt-memory` + embeddings Qwen3 (dégrade si down) | ✅ validé 17/06 (rappel cross-session OK) | +| **5b — Mémoire long-terme** | Qdrant `stt-memory` + embeddings (dégrade si down) | ✅ validé 17/06 (rappel cross-session OK) | | **5c — Réparation Qdrant** | drop `funk-docs` corrompu + restart (s01) | ✅ (17/06) | | **5d — Embeddings dédiés** | `nomic-embed-text` (dim 768) sur gpu-01 `:1238` → recherche plus précise | ✅ (rôle llama_server + migration auto collection) | +| **5e — Fix thinking Qwen3** | `/no_think` (content vide / timeout 502) + fallback reasoning_content | ✅ (17/06) | | **6 — Auto-start client** | `install-service.sh` (systemd --user) + kiosk | ⏳ | | **7 — Outils Hermes** | « agir sur Funk » via gateway `:8080` (API à spécifier) | ⏳ | diff --git a/stt/server/README.md b/stt/server/README.md index e57f6b7..0bd5035 100644 --- a/stt/server/README.md +++ b/stt/server/README.md @@ -31,12 +31,22 @@ la cohérence de la mémoire process. Mémoire long-terme Qdrant = phase 5b.) | `STT_ALLOWED_MODELS` | `hermes-default,qwen3-8b,claude-sonnet-4-6,claude-opus-4-7` | alias autorisés (demandables par le client) | | `STT_SYSTEM_PROMPT` | prompt vocal FR concis | persona | | `STT_MAX_TOKENS` / `STT_TEMPERATURE` | `200` / `0.7` | génération | +| `STT_DISABLE_THINKING` | `true` | ajoute `/no_think` au prompt (désactive le raisonnement Qwen3) | | `STT_MEMORY_LONGTERM` | `true` | mémoire long-terme Qdrant (dégrade si injoignable) | | `STT_QDRANT_URL` | `http://192.168.10.1:6333` | Qdrant (s01) | | `STT_EMBED_URL` | `http://192.168.10.20:1238/v1/embeddings` | embeddings nomic-embed-text (gpu-01 `:1238`, dim 768) | | `STT_EMBED_MODEL` | `nomic-embed-text` | alias du modèle d'embedding | | `STT_MEMORY_TOPK` | `3` | nombre de souvenirs injectés | +## Caveat Qwen3 — mode « thinking » + +Qwen3 est un modèle de raisonnement : par défaut il « réfléchit » avant de répondre. Avec un +`max_tokens` faible (200), il dépense tout le budget dans `reasoning_content` → `content` **vide** ; +sur certaines questions il réfléchit longtemps → **timeout** (502 `upstream LiteLLM : `). `brain.py` +ajoute donc le token de contrôle **`/no_think`** au prompt système (`STT_DISABLE_THINKING=true`, +inoffensif pour les modèles non-Qwen) et, par sécurité, récupère `reasoning_content` si `content` +est vide. Voir le caveat partagé dans `admin/ia/llama_server.md`. + ## Dev local ```bash