mirror of
https://github.com/Alkatrazz24/Funk-lab.git
synced 2026-07-08 06:24:42 +02:00
docs: réorganisation complète de admin/ en 4 domaines thématiques
Structure avant : 20 fichiers à plat dans admin/ — difficile à naviguer.
Structure après : 4 sous-répertoires thématiques + index clair.
Réorganisation :
admin/ops/ → cluster.md, ansible.md, systeme.md
admin/infra/ → reseau.md, nfs.md, dnsmasq.md, ssh.md
admin/k8s/ → talos.md, argocd.md, monitoring.md
admin/ia/ → llama_server.md, rocm.md, litellm.md, hermes.md
Suppressions :
- ask-agent.md : contenu fusionné dans ia/hermes.md (section ask-agent)
- lm_studio.md : obsolète (LM Studio remplacé par llama-server)
Mises à jour contenu :
- ia/hermes.md : fusion complète avec ask-agent.md (profils, skills,
SOUL.md, ask-agent CLI, dépannage) — doc unifiée sans redondance
- ops/cluster.md : section GitOps réduite à 2 lignes + lien argocd.md
- incidents.md : tableau de résumé en tête + 4 nouveaux incidents
(Grafana OOMKilled, AlertManager null receiver, llama-server 501,
nftables règle après drop)
- README.md : réécrit — navigation rapide + index par domaine
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d552abd2ef
commit
5bcf95b82e
19 changed files with 633 additions and 677 deletions
428
admin/ia/hermes.md
Normal file
428
admin/ia/hermes.md
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
# Hermes Agent
|
||||
|
||||
Hermes Agent tourne en deux services systemd sur **storage-01** :
|
||||
- `hermes-agent` — gateway (messagerie, inférence, outils)
|
||||
- `hermes-dashboard` — interface web (port 9119)
|
||||
|
||||
Il passe par **LiteLLM** (`:4000`) pour toute inférence — Qwen local ou Claude API.
|
||||
Les données persistantes sont sur le RAID5 : `/srv/data/hermes`.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Profils Hermes → LiteLLM Proxy (:4000) → llama-server / API Anthropic
|
||||
├── qwen3-8b → gpu-01:1234 (GPU RX 6700XT)
|
||||
├── qwen3-1.7b-system → gpu-01:1236 (CPU 14 threads)
|
||||
├── qwen3-1.7b-monitor → gpu-01:1237 (CPU 14 threads)
|
||||
├── claude-sonnet-4-6 → api.anthropic.com
|
||||
└── claude-opus-4-7 → api.anthropic.com
|
||||
|
||||
Depuis Hermes (TUI ou ask-agent) :
|
||||
funk-ai (principal) ──┐
|
||||
brain ├── LM_BASE_URL=http://127.0.0.1:4000/v1
|
||||
system │
|
||||
monitor ──┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Profils
|
||||
|
||||
| Profil | Alias CLI | Modèle | Usage |
|
||||
|---|---|---|---|
|
||||
| `funk-ai` ◆ | `funk-ai` | qwen3-8b (GPU, ~35 tok/s) | Principal — par défaut |
|
||||
| `brain` | `brain` | claude-sonnet-4-6 (API) | Analyse complexe — facturé |
|
||||
| `system` | `system` | qwen3-1.7b-system (CPU, ~21 tok/s) | Traitement texte rapide |
|
||||
| `monitor` | `monitor` | qwen3-1.7b-monitor (CPU, ~21 tok/s) | Évaluation état services |
|
||||
|
||||
`◆` = profil actif par défaut
|
||||
|
||||
```bash
|
||||
# Lancer un profil (nouvelle session TUI)
|
||||
funk-ai # Qwen3-8B GPU
|
||||
brain # Claude Sonnet
|
||||
system # Qwen3-1.7B CPU
|
||||
monitor # Qwen3-1.7B CPU
|
||||
|
||||
# Oneshot
|
||||
sudo -i -u hermes bash -c 'HERMES_HOME=/srv/data/hermes hermes --profile system -z "ta question"'
|
||||
|
||||
# Changer le profil par défaut
|
||||
sudo -i -u hermes bash -c 'HERMES_HOME=/srv/data/hermes hermes profile use funk-ai'
|
||||
|
||||
# Lister les profils
|
||||
sudo -i -u hermes bash -c 'HERMES_HOME=/srv/data/hermes hermes profile list'
|
||||
```
|
||||
|
||||
> Pas de changement de profil à chaud dans le TUI — ouvrir une nouvelle session.
|
||||
|
||||
---
|
||||
|
||||
## Service systemd
|
||||
|
||||
```bash
|
||||
sudo systemctl status hermes-agent
|
||||
sudo systemctl restart hermes-agent
|
||||
sudo journalctl -u hermes-agent -f
|
||||
sudo journalctl -u hermes-agent -n 50
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## TUI (chat interactif)
|
||||
|
||||
Le TUI nécessite un TTY et doit tourner sous le compte `hermes` :
|
||||
|
||||
```bash
|
||||
ssh storage-01
|
||||
sudo -i -u hermes
|
||||
cd /srv/data/hermes
|
||||
hermes --tui
|
||||
```
|
||||
|
||||
> Lancer depuis un autre compte génère des "gateway error" — toujours utiliser le compte hermes.
|
||||
|
||||
---
|
||||
|
||||
## Dashboard Web
|
||||
|
||||
Accessible depuis le poste admin uniquement (`192.168.1.10`) :
|
||||
|
||||
```
|
||||
http://192.168.1.200:9119
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl status hermes-dashboard
|
||||
sudo systemctl restart hermes-dashboard
|
||||
sudo journalctl -u hermes-dashboard -f
|
||||
```
|
||||
|
||||
> L'onglet Chat (TUI via WebSocket) ne fonctionne pas dans le dashboard. Utiliser le TUI SSH.
|
||||
|
||||
---
|
||||
|
||||
## CLI
|
||||
|
||||
```bash
|
||||
# Chat interactif (depuis storage-01, compte hermes)
|
||||
cd /srv/data/hermes && hermes chat
|
||||
|
||||
# Question one-shot
|
||||
cd /srv/data/hermes && hermes -z "ta question"
|
||||
|
||||
# Statut global
|
||||
hermes status
|
||||
|
||||
# Diagnostics
|
||||
hermes doctor
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### config.yaml (`/srv/data/hermes/config.yaml`)
|
||||
|
||||
```yaml
|
||||
model:
|
||||
provider: lmstudio
|
||||
base_url: "http://127.0.0.1:4000/v1"
|
||||
default: "hermes-default"
|
||||
context_length: 65536
|
||||
|
||||
gateway:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
```
|
||||
|
||||
### .env (`/srv/data/hermes/.env`)
|
||||
|
||||
```bash
|
||||
LM_BASE_URL=http://127.0.0.1:4000/v1
|
||||
LM_API_KEY=lm-studio # valeur exacte obligatoire
|
||||
```
|
||||
|
||||
### Variables d'environnement (service systemd)
|
||||
|
||||
| Variable | Valeur |
|
||||
|---|---|
|
||||
| `HOME` | `/opt/hermes` |
|
||||
| `HERMES_HOME` | `/srv/data/hermes` |
|
||||
| `LM_BASE_URL` | `http://127.0.0.1:4000/v1` |
|
||||
| `LM_API_KEY` | `lm-studio` |
|
||||
|
||||
---
|
||||
|
||||
## SOUL.md — Identité des profils
|
||||
|
||||
Chaque profil peut avoir un fichier `SOUL.md` chargé en **slot #1** du system prompt.
|
||||
Il définit l'identité de l'agent, son environnement, ses outils et son comportement.
|
||||
Rechargé à chaque message sans redémarrage du service.
|
||||
|
||||
```
|
||||
/srv/data/hermes/profiles/<profil>/SOUL.md
|
||||
```
|
||||
|
||||
Sources versionnées dans le repo :
|
||||
```
|
||||
hermes-skills/souls/funk-ai.md → profil funk-ai
|
||||
hermes-skills/souls/system.md → profil system
|
||||
hermes-skills/souls/monitor.md → profil monitor
|
||||
hermes-skills/souls/brain.md → profil brain
|
||||
```
|
||||
|
||||
Le SOUL.md de `funk-ai` contient : environnement cluster (IPs, machines, services),
|
||||
accès SSH gpu-01, règles `ask-agent`, routing system/monitor/brain, style de réponse.
|
||||
|
||||
```bash
|
||||
# Déployer un SOUL.md depuis le repo
|
||||
scp hermes-skills/souls/funk-ai.md storage-01:/tmp/soul.md
|
||||
ssh storage-01 "sudo cp /tmp/soul.md /srv/data/hermes/profiles/funk-ai/SOUL.md"
|
||||
# Pas de redémarrage nécessaire — rechargé automatiquement
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Skills
|
||||
|
||||
Les skills sont des fichiers `SKILL.md` chargés en contexte dans chaque session Hermes.
|
||||
|
||||
> **Règle critique** : un skill doit être présent dans **deux endroits** :
|
||||
> - `$HERMES_HOME/skills/<cat>/<nom>/SKILL.md` — répertoire global (référence)
|
||||
> - `$HERMES_HOME/profiles/<profil>/skills/<cat>/<nom>/SKILL.md` — chargé par le profil
|
||||
>
|
||||
> Placer un skill uniquement dans le global ne suffit pas.
|
||||
|
||||
```bash
|
||||
# Lister les skills actifs du profil courant
|
||||
sudo -u hermes env HERMES_HOME=/srv/data/hermes hermes skills list
|
||||
|
||||
# Vérifier qu'un skill est dans le profil funk-ai
|
||||
sudo ls /srv/data/hermes/profiles/funk-ai/skills/funk/
|
||||
```
|
||||
|
||||
### Skills custom Funk
|
||||
|
||||
| Skill | Catégorie | Usage |
|
||||
|---|---|---|
|
||||
| `agent-delegation` | `funk` | Déléguer des sous-tâches aux agents system/monitor/brain via `ask-agent` |
|
||||
|
||||
### Ajouter un skill custom
|
||||
|
||||
```bash
|
||||
# 1. Créer dans le repo (versionné)
|
||||
mkdir -p hermes-skills/funk/<nom-skill>
|
||||
vim hermes-skills/funk/<nom-skill>/SKILL.md
|
||||
|
||||
# 2. Déployer dans le répertoire global
|
||||
sudo mkdir -p /srv/data/hermes/skills/funk/<nom-skill>
|
||||
sudo cp hermes-skills/funk/<nom-skill>/SKILL.md /srv/data/hermes/skills/funk/<nom-skill>/
|
||||
|
||||
# 3. Copier dans le profil cible
|
||||
sudo mkdir -p /srv/data/hermes/profiles/funk-ai/skills/funk/<nom-skill>
|
||||
sudo cp /srv/data/hermes/skills/funk/<nom-skill>/SKILL.md \
|
||||
/srv/data/hermes/profiles/funk-ai/skills/funk/<nom-skill>/
|
||||
sudo chown -R hermes:hermes /srv/data/hermes/profiles/funk-ai/skills/funk
|
||||
|
||||
# 4. Redémarrer + vérifier
|
||||
sudo systemctl restart hermes-agent
|
||||
sudo -u hermes env HERMES_HOME=/srv/data/hermes hermes skills list | grep funk
|
||||
```
|
||||
|
||||
### Mettre à jour un skill existant
|
||||
|
||||
```bash
|
||||
vim hermes-skills/funk/agent-delegation/SKILL.md
|
||||
|
||||
sudo cp hermes-skills/funk/agent-delegation/SKILL.md \
|
||||
/srv/data/hermes/skills/funk/agent-delegation/SKILL.md
|
||||
sudo cp hermes-skills/funk/agent-delegation/SKILL.md \
|
||||
/srv/data/hermes/profiles/funk-ai/skills/funk/agent-delegation/SKILL.md
|
||||
sudo chown hermes:hermes \
|
||||
/srv/data/hermes/profiles/funk-ai/skills/funk/agent-delegation/SKILL.md
|
||||
|
||||
sudo systemctl restart hermes-agent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ask-agent — Délégation inter-agents
|
||||
|
||||
`ask-agent` permet à Hermes (profil `funk-ai`) de déléguer des sous-tâches
|
||||
aux agents spécialisés. Le skill `funk/agent-delegation` lui enseigne quand et comment.
|
||||
|
||||
```
|
||||
funk-ai (Qwen3-8B GPU)
|
||||
│
|
||||
│ Terminal: ask-agent <agent> "question"
|
||||
▼
|
||||
ask-agent (/usr/local/bin/ask-agent)
|
||||
│ POST http://127.0.0.1:4000/v1/chat/completions
|
||||
▼
|
||||
LiteLLM Proxy (:4000)
|
||||
├── ask-agent system → qwen3-1.7b-system (CPU :1236)
|
||||
├── ask-agent monitor → qwen3-1.7b-monitor (CPU :1237)
|
||||
├── ask-agent brain → claude-sonnet-4-6 (API Anthropic)
|
||||
└── ask-agent funk-ai → qwen3-8b (GPU :1234)
|
||||
```
|
||||
|
||||
### Agents disponibles
|
||||
|
||||
| Agent | Modèle | Usage idéal |
|
||||
|---|---|---|
|
||||
| `system` | Qwen3-1.7B CPU (:1236) | Traitement texte : résumés, formatage, parsing, calculs Linux |
|
||||
| `monitor` | Qwen3-1.7B CPU (:1237) | Évaluation santé : logs systemd, métriques, état des services |
|
||||
| `brain` | Claude Sonnet 4.6 (API) | Raisonnement complexe, architecture — facturé |
|
||||
| `funk-ai` | Qwen3-8B GPU (:1234) | Tâches générales (agent principal lui-même) |
|
||||
|
||||
### system vs monitor
|
||||
|
||||
| Critère | `system` | `monitor` |
|
||||
|---|---|---|
|
||||
| Type de question | "Qu'est-ce que ça signifie ?" / "Résume ça" | "Y a-t-il des erreurs ?" / "Ce service est-il sain ?" |
|
||||
| Output | Réponse directe, liste de faits | Verdict OK/WARNING/ERROR + actions correctives |
|
||||
|
||||
### Utilisation
|
||||
|
||||
```bash
|
||||
# system : traitement de texte
|
||||
ask-agent system "que signifie cette sortie df -h : <texte>"
|
||||
ask-agent system "convertis 8192 MiB en GiB"
|
||||
|
||||
# monitor : évaluation santé
|
||||
ask-agent monitor "logs litellm : <texte> — erreurs ?"
|
||||
ask-agent monitor "status llama-server : <texte> — service sain ?"
|
||||
|
||||
# brain : analyse complexe
|
||||
ask-agent brain "architecture optimale pour ce schéma k8s : <contexte>" --max-tokens 3000
|
||||
|
||||
# Avec prompt système personnalisé
|
||||
ask-agent monitor "est-ce normal ?" --system "Tu es expert Linux, réponds en 1 phrase max."
|
||||
```
|
||||
|
||||
Pattern typique — Hermes collecte en local, délègue l'analyse :
|
||||
```
|
||||
Terminal: systemctl --state=failed --no-pager
|
||||
Terminal: ask-agent monitor "voici les services en erreur : <résultat> — résume les problèmes"
|
||||
```
|
||||
|
||||
### Paramètres du script
|
||||
|
||||
Déployé sur storage-01 : `/usr/local/bin/ask-agent`
|
||||
Source versionnée : `ansible/roles/litellm/files/ask-agent`
|
||||
|
||||
| Paramètre | Valeur |
|
||||
|---|---|
|
||||
| LiteLLM URL | `http://127.0.0.1:4000/v1/chat/completions` |
|
||||
| API key | `lm-studio` |
|
||||
| Timeout | 120s (curl) |
|
||||
| `/no_think` | Préfixé automatiquement pour system et monitor (évite la surconsommation de tokens) |
|
||||
|
||||
```bash
|
||||
# Redéployer via Ansible
|
||||
ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags litellm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Arborescence
|
||||
|
||||
Depuis l'incident 2026-05-13, le code est sur le SSD OS et les données sur le RAID5.
|
||||
|
||||
```
|
||||
/opt/hermes/ → home utilisateur hermes (SSD OS)
|
||||
├── .local/bin/hermes → wrapper bash → venv hermes-agent
|
||||
└── .hermes/hermes-agent/ → code source + venv Python
|
||||
├── venv/ → environnement Python (uv)
|
||||
├── hermes_cli/ → source CLI
|
||||
└── web/ → source frontend dashboard
|
||||
|
||||
/srv/data/hermes/ → HERMES_HOME (RAID5) — données persistantes
|
||||
├── config.yaml → configuration profil par défaut (géré Ansible)
|
||||
├── .env → LM_BASE_URL, LM_API_KEY (géré Ansible)
|
||||
├── memories/ → mémoire persistante profil par défaut
|
||||
├── sessions/ → historique sessions
|
||||
├── logs/ → logs
|
||||
├── skills/ → skills installées
|
||||
├── state.db → base SQLite état agent
|
||||
└── profiles/ → profils isolés
|
||||
├── funk-ai/ → config.yaml, memories/, sessions/, state.db, SOUL.md
|
||||
├── brain/
|
||||
├── system/
|
||||
└── monitor/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mise à jour de Hermes
|
||||
|
||||
```bash
|
||||
sudo systemctl stop hermes-dashboard hermes-agent
|
||||
|
||||
sudo -i -u hermes bash -c 'HOME=/opt/hermes HERMES_HOME=/srv/data/hermes hermes update'
|
||||
|
||||
sudo systemctl start hermes-agent hermes-dashboard
|
||||
sudo systemctl status hermes-agent hermes-dashboard --no-pager
|
||||
```
|
||||
|
||||
Si rebuild frontend nécessaire après mise à jour majeure :
|
||||
```bash
|
||||
sudo -u hermes bash -c \
|
||||
'HOME=/opt/hermes && cd /opt/hermes/.hermes/hermes-agent/web && npm install && npm run build'
|
||||
sudo systemctl restart hermes-dashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dépannage
|
||||
|
||||
### ask-agent retourne du garbage
|
||||
|
||||
Modèle GGUF potentiellement corrompu (signe d'erreur disque).
|
||||
```bash
|
||||
ssh g01 "sudo systemctl status llama-server-system"
|
||||
ssh g01 "md5sum /mnt/models/<chemin-gguf>"
|
||||
```
|
||||
|
||||
### ask-agent timeout
|
||||
|
||||
LiteLLM ou llama-server ne répond pas.
|
||||
```bash
|
||||
ssh s01 "curl -s http://localhost:4000/health -H 'Authorization: Bearer lm-studio'"
|
||||
ssh g01 "systemctl status llama-server-system llama-server-monitor"
|
||||
```
|
||||
|
||||
### Le skill n'est pas chargé
|
||||
|
||||
```bash
|
||||
sudo ls /srv/data/hermes/profiles/funk-ai/skills/funk/agent-delegation/
|
||||
```
|
||||
Si absent → copier depuis `/srv/data/hermes/skills/funk/agent-delegation/` et redémarrer.
|
||||
|
||||
### Hermes fait SSH vers storage-01
|
||||
|
||||
Le skill lui dit "tu es déjà sur storage-01". Une session déjà ouverte charge l'ancien skill.
|
||||
Fermer le TUI et en ouvrir un nouveau après chaque modification.
|
||||
|
||||
---
|
||||
|
||||
## Points d'attention
|
||||
|
||||
| Sujet | Détail |
|
||||
|---|---|
|
||||
| Code vs données | Code + venv : `/opt/hermes/.hermes/hermes-agent/` (SSD OS) — Profils/données : `/srv/data/hermes/` (RAID5) |
|
||||
| `HERMES_HOME` | Toujours préfixer les commandes hermes avec `HERMES_HOME=/srv/data/hermes` |
|
||||
| `LM_API_KEY` | Doit valoir `lm-studio` exactement |
|
||||
| `context_length` | Hermes exige 64k minimum — override via `model.context_length: 65536` dans config.yaml |
|
||||
| `hermes -z` path | Toujours lancer depuis `/srv/data/hermes` (cherche .git en remontant) |
|
||||
| LiteLLM requis | `litellm.service` doit tourner avant `hermes-agent` |
|
||||
| Skills double emplacement | Tout skill custom doit être dans `skills/` ET dans `profiles/funk-ai/skills/` |
|
||||
| Restart après skill | `systemctl restart hermes-agent` obligatoire après ajout ou modification d'un skill |
|
||||
| brain coûteux | Claude Sonnet API — réserver aux analyses que system/monitor ne peuvent pas faire |
|
||||
| Gemma 4 interdit | Crash ROCm sur prompts >800 tokens |
|
||||
| Dashboard | Accessible uniquement depuis `192.168.1.10:9119` (restreint nftables) |
|
||||
| TUI | `hermes --tui` nécessite un TTY — utiliser SSH interactif sous le compte hermes |
|
||||
| `systemd-journal` | Le service inclut ce groupe — `journalctl` fonctionne sans sudo dans le Terminal de Hermes |
|
||||
135
admin/ia/litellm.md
Normal file
135
admin/ia/litellm.md
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
# LiteLLM — Proxy LLM unifié (storage-01)
|
||||
|
||||
LiteLLM tourne en service systemd sur **storage-01** (`127.0.0.1:4000`).
|
||||
Il route les requêtes OpenAI-compatibles vers le bon backend selon le modèle demandé.
|
||||
|
||||
---
|
||||
|
||||
## Flux
|
||||
|
||||
```
|
||||
Hermes / ask-agent / Open WebUI / n8n
|
||||
│
|
||||
▼ http://127.0.0.1:4000/v1 (Authorization: Bearer lm-studio)
|
||||
LiteLLM Proxy
|
||||
├── hermes-default → qwen3-8b → llama-server gpu-01 :1234 (GPU)
|
||||
├── qwen3-8b → llama-server gpu-01 :1234 (GPU, gratuit)
|
||||
├── qwen3-1.7b-system → llama-server gpu-01 :1236 (CPU 14 threads, gratuit)
|
||||
├── qwen3-1.7b-monitor → llama-server gpu-01 :1237 (CPU 14 threads, gratuit)
|
||||
├── claude-sonnet-4-6 → api.anthropic.com (cloud, payant)
|
||||
└── claude-opus-4-7 → api.anthropic.com (cloud, payant)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Service systemd
|
||||
|
||||
```bash
|
||||
# Depuis storage-01
|
||||
sudo systemctl status litellm
|
||||
sudo systemctl restart litellm
|
||||
sudo journalctl -u litellm -f
|
||||
sudo journalctl -u litellm -n 50
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modèles disponibles
|
||||
|
||||
| Nom dans l'API | Backend | Coût |
|
||||
|---|---|---|
|
||||
| `hermes-default` | qwen3-8b sur gpu-01 :1234 (GPU) | Gratuit |
|
||||
| `qwen3-8b` | llama-server gpu-01 :1234 (ROCm 7.x) | Gratuit |
|
||||
| `qwen3-1.7b-system` | llama-server gpu-01 :1236 (CPU, 14 threads) | Gratuit |
|
||||
| `qwen3-1.7b-monitor` | llama-server gpu-01 :1237 (CPU, 14 threads) | Gratuit |
|
||||
| `claude-sonnet-4-6` | Anthropic API | ~$3/$15 par million tokens in/out |
|
||||
| `claude-opus-4-7` | Anthropic API | Plus cher, meilleur raisonnement |
|
||||
|
||||
> `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).
|
||||
|
||||
---
|
||||
|
||||
## Switch rapide avec hermes-switch
|
||||
|
||||
Script déployé sur storage-01 :
|
||||
|
||||
```bash
|
||||
sudo hermes-switch status # voir le modèle actuel de hermes-default
|
||||
sudo hermes-switch qwen # Qwen2.5-14B local (gratuit, ~35 tok/s)
|
||||
sudo hermes-switch claude # Claude Sonnet 4.6 (payant, ~1-2$ par session debug)
|
||||
```
|
||||
|
||||
Le script modifie `/etc/litellm/config.yaml` et redémarre litellm automatiquement.
|
||||
Source : `roles/litellm/files/hermes-switch`.
|
||||
|
||||
### Coût Claude
|
||||
|
||||
| Session type | Tokens input | Coût estimé |
|
||||
|---|---|---|
|
||||
| Debug simple (5 échanges) | ~80k | ~$0.24 |
|
||||
| Debug complexe (10 échanges) | ~375k | ~$1.12 |
|
||||
| Utilisation courante | — | Utiliser Qwen |
|
||||
|
||||
---
|
||||
|
||||
## Validation API
|
||||
|
||||
```bash
|
||||
# Depuis storage-01 — master_key = lm-studio
|
||||
curl http://127.0.0.1:4000/v1/models \
|
||||
-H "Authorization: Bearer lm-studio" | python3 -m json.tool
|
||||
|
||||
# Test inférence Qwen (local)
|
||||
curl http://127.0.0.1:4000/v1/chat/completions \
|
||||
-H "Authorization: Bearer lm-studio" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model": "qwen2.5-14b-instruct", "messages": [{"role": "user", "content": "Dis bonjour"}], "max_tokens": 30}'
|
||||
|
||||
# Test inférence Claude
|
||||
curl http://127.0.0.1:4000/v1/chat/completions \
|
||||
-H "Authorization: Bearer lm-studio" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model": "claude-sonnet-4-6", "messages": [{"role": "user", "content": "Dis bonjour"}], "max_tokens": 30}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
Fichier : `/etc/litellm/config.yaml` (géré par Ansible, propriété `litellm:litellm`, mode `0640`)
|
||||
|
||||
La clé API Anthropic est injectée via `ANTHROPIC_API_KEY` dans l'unit systemd —
|
||||
elle vient du vault Ansible (`vault_anthropic_api_key`). Jamais en clair dans config.yaml.
|
||||
|
||||
**master_key** : `lm-studio` — doit correspondre à `LM_API_KEY` dans le `.env` Hermes.
|
||||
|
||||
---
|
||||
|
||||
## Ajouter un modèle
|
||||
|
||||
1. Modifier `roles/litellm/templates/config.yaml.j2` :
|
||||
```yaml
|
||||
- model_name: claude-haiku-4-5
|
||||
litellm_params:
|
||||
model: anthropic/claude-haiku-4-5-20251001
|
||||
api_key: os.environ/ANTHROPIC_API_KEY
|
||||
```
|
||||
|
||||
2. Redéployer :
|
||||
```bash
|
||||
ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags litellm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Points d'attention
|
||||
|
||||
| Sujet | Détail |
|
||||
|---|---|
|
||||
| Accès réseau | `127.0.0.1` uniquement — pour exposer au cluster, changer `litellm_host: 0.0.0.0` + ouvrir firewall |
|
||||
| master_key | `lm-studio` — doit correspondre exactement à `LM_API_KEY` dans le `.env` Hermes |
|
||||
| Clé Anthropic | `ANTHROPIC_API_KEY` dans l'env systemd — vault Ansible |
|
||||
| Coût Claude | Surveiller la consommation sur console.anthropic.com |
|
||||
| 404 /api/v1/models | Hermes appelle `/api/v1/models` à l'init (retourne 404) — normal, ne bloque pas |
|
||||
| hermes-switch status | Utilise `grep -A3` — si le bloc hermes-default a une structure différente, ajuster |
|
||||
191
admin/ia/llama_server.md
Normal file
191
admin/ia/llama_server.md
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
# 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`).
|
||||
API 100% compatible OpenAI — remplace LM Studio pour l'inférence.
|
||||
|
||||
---
|
||||
|
||||
## Trois 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) |
|
||||
|
||||
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`).
|
||||
|
||||
---
|
||||
|
||||
## Service systemd
|
||||
|
||||
```bash
|
||||
# Instance GPU (principale)
|
||||
sudo systemctl status llama-server
|
||||
sudo systemctl restart llama-server
|
||||
sudo journalctl -u llama-server -f
|
||||
|
||||
# Instance CPU — profil system
|
||||
sudo systemctl status llama-server-system
|
||||
sudo systemctl restart llama-server-system
|
||||
sudo journalctl -u llama-server-system -f
|
||||
|
||||
# Instance CPU — profil monitor
|
||||
sudo systemctl status llama-server-monitor
|
||||
sudo systemctl restart llama-server-monitor
|
||||
sudo journalctl -u llama-server-monitor -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modèle actuel (GPU)
|
||||
|
||||
| Paramètre | Valeur |
|
||||
|---|---|
|
||||
| Modèle | Qwen3-8B Q4_K_M |
|
||||
| Alias API | `qwen3-8b` |
|
||||
| Chemin | `/mnt/models/bartowski/Qwen3-8B-GGUF/Qwen3-8B-Q4_K_M.gguf` |
|
||||
| Contexte | 32768 tokens |
|
||||
| GPU offload | 99 layers (tout sur GPU) |
|
||||
| Parallélisme | 1 slot (requis pour Hermes — voir bug parallel) |
|
||||
| Embeddings | activés (`--embeddings --pooling mean`) |
|
||||
|
||||
### Contrainte VRAM (12 GB RX 6700XT)
|
||||
|
||||
| Élément | VRAM |
|
||||
|---|---|
|
||||
| Modèle Q4_K_M 8B | ~5 GB |
|
||||
| KV cache à 32768 ctx | ~4 GB |
|
||||
| **Total** | **~9 GB** ✅ |
|
||||
|
||||
---
|
||||
|
||||
## Embeddings
|
||||
|
||||
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`).
|
||||
|
||||
```bash
|
||||
# Test embeddings depuis storage-01
|
||||
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)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performances (RX 6700XT, ROCm 7.x)
|
||||
|
||||
| Métrique | Qwen3-1.7B (CPU) | Qwen3-8B (GPU) |
|
||||
|---|---|---|
|
||||
| Prefill | ~50 tok/s | ~300 tok/s |
|
||||
| Génération | ~15 tok/s | ~60 tok/s |
|
||||
| TTFT Hermes (15k tokens) | ~300s | ~50s |
|
||||
| VRAM modèle | — (CPU only) | ~5 GB |
|
||||
|
||||
---
|
||||
|
||||
## Validation API
|
||||
|
||||
```bash
|
||||
# Depuis storage-01 ou n'importe quelle machine du LAN cluster
|
||||
curl -s http://192.168.10.20:1234/v1/models | jq '.data[].id'
|
||||
|
||||
# Test inférence rapide (GPU)
|
||||
curl http://192.168.10.20:1234/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"model": "qwen3-8b",
|
||||
"messages": [{"role": "user", "content": "Dis bonjour"}],
|
||||
"max_tokens": 50
|
||||
}'
|
||||
|
||||
# Test instances CPU
|
||||
curl -s http://192.168.10.20:1236/v1/models | jq '.data[].id'
|
||||
curl -s http://192.168.10.20:1237/v1/models | jq '.data[].id'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Métriques Prometheus
|
||||
|
||||
Le flag `--metrics` est requis dans le service systemd pour activer l'endpoint `/metrics`.
|
||||
Sans lui, llama-server retourne `501 Not Implemented`.
|
||||
|
||||
```bash
|
||||
# Vérifier que les métriques sont disponibles
|
||||
curl -s http://192.168.10.20:1234/metrics | grep llamacpp
|
||||
|
||||
# Métriques clés exposées
|
||||
curl -s http://192.168.10.20:1234/metrics | grep -E \
|
||||
"llamacpp:prompt_tokens_total|llamacpp:tokens_predicted_total|llamacpp:requests_deferred|llamacpp:kv_cache_usage_ratio"
|
||||
```
|
||||
|
||||
| Métrique | Description |
|
||||
|---|---|
|
||||
| `llamacpp:prompt_tokens_total` | Tokens de prompt traités (cumul) |
|
||||
| `llamacpp:tokens_predicted_total` | Tokens générés (cumul) |
|
||||
| `llamacpp:prompt_tokens_seconds` | Débit prefill (tok/s) |
|
||||
| `llamacpp:predicted_tokens_seconds` | Débit génération (tok/s) |
|
||||
| `llamacpp:requests_deferred` | Requêtes en file d'attente (backpressure) |
|
||||
| `llamacpp:kv_cache_usage_ratio` | Occupation KV cache (0–1) |
|
||||
| `llamacpp:kv_cache_tokens` | Tokens actuellement en KV cache |
|
||||
|
||||
Ces métriques sont scrapées par Prometheus via les jobs `llama-server-gpu`, `llama-server-system`, `llama-server-monitor` définis dans `k8s/infra/monitoring/values.yaml`.
|
||||
|
||||
---
|
||||
|
||||
## Changer de modèle
|
||||
|
||||
1. Modifier `host_vars/gpu-01/vars.yml` :
|
||||
```yaml
|
||||
llama_model_path: "/mnt/models/bartowski/NouveauModele.gguf"
|
||||
llama_model_alias: "nouveau-alias"
|
||||
llama_ctx_size: 32768 # ajuster selon VRAM disponible
|
||||
```
|
||||
|
||||
2. Redéployer :
|
||||
```bash
|
||||
ansible-playbook -i inventory.yml playbooks/gpu-01.yml --tags llama_server
|
||||
```
|
||||
|
||||
3. Mettre à jour LiteLLM (alias `hermes-default`) :
|
||||
```bash
|
||||
ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags litellm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build (source)
|
||||
|
||||
```bash
|
||||
# Sur gpu-01 — rebuild si besoin
|
||||
cd /opt/llama.cpp
|
||||
git pull
|
||||
cmake -B build \
|
||||
-DGGML_HIP=ON \
|
||||
-DAMDGPU_TARGETS=gfx1030 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ \
|
||||
-DCMAKE_PREFIX_PATH=/opt/rocm
|
||||
cmake --build build --target llama-server -j$(nproc)
|
||||
sudo systemctl restart llama-server
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Points d'attention
|
||||
|
||||
| Sujet | Détail |
|
||||
|---|---|
|
||||
| GPU non officiel | RX 6700XT (gfx1031) — `HSA_OVERRIDE_GFX_VERSION=10.3.0` dans le service |
|
||||
| ROCm version | 7.2.3 — libs dans `/opt/rocm` |
|
||||
| --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 |
|
||||
| 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 |
|
||||
101
admin/ia/rocm.md
Normal file
101
admin/ia/rocm.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# ROCm — GPU AMD RX 6700XT (gpu-01)
|
||||
|
||||
ROCm tourne directement sur l'hôte AlmaLinux (pas dans des conteneurs).
|
||||
La RX 6700XT (gfx1031) n'est pas officiellement supportée → `HSA_OVERRIDE_GFX_VERSION=10.3.0` obligatoire.
|
||||
|
||||
---
|
||||
|
||||
## Vérification de base
|
||||
|
||||
```bash
|
||||
# Le GPU est-il détecté par le kernel ?
|
||||
ssh g01 "lspci | grep -i amd | grep -i vga"
|
||||
|
||||
# Le module amdgpu est-il chargé ?
|
||||
ssh g01 "lsmod | grep amdgpu"
|
||||
|
||||
# ROCm voit-il le GPU ? (doit lister la RX 6700XT)
|
||||
ssh g01 "HSA_OVERRIDE_GFX_VERSION=10.3.0 rocminfo | grep -A5 'Agent 2'"
|
||||
|
||||
# Version ROCm installée
|
||||
ssh g01 "rocminfo | grep 'ROCk'"
|
||||
|
||||
# GPU info complet
|
||||
ssh g01 "HSA_OVERRIDE_GFX_VERSION=10.3.0 rocminfo"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Variable HSA_OVERRIDE
|
||||
|
||||
```bash
|
||||
# Vérifier qu'elle est bien définie system-wide
|
||||
ssh g01 "cat /etc/environment | grep HSA"
|
||||
|
||||
# Vérifier dans profile.d (sessions interactives)
|
||||
ssh g01 "cat /etc/profile.d/rocm.sh"
|
||||
|
||||
# Tester manuellement (si la variable n'est pas dans l'env courant)
|
||||
ssh g01 "HSA_OVERRIDE_GFX_VERSION=10.3.0 rocminfo | grep gfx"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modules kernel
|
||||
|
||||
```bash
|
||||
# Statut du module amdgpu
|
||||
ssh g01 "lsmod | grep amdgpu"
|
||||
|
||||
# Recharger le module (si nécessaire)
|
||||
ssh g01 "sudo modprobe -r amdgpu && sudo modprobe amdgpu"
|
||||
|
||||
# Logs kernel liés au GPU
|
||||
ssh g01 "sudo dmesg | grep -i amdgpu | tail -20"
|
||||
ssh g01 "sudo dmesg | grep -i 'drm\|gpu' | tail -20"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Repos AMD
|
||||
|
||||
```bash
|
||||
# Vérifier les repos installés
|
||||
ssh g01 "sudo dnf repolist | grep -i 'amd\|rocm'"
|
||||
|
||||
# Voir les packages ROCm installés
|
||||
ssh g01 "sudo dnf list installed | grep -i rocm"
|
||||
ssh g01 "sudo rpm -qa | grep rocm"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Groupes utilisateur (accès GPU)
|
||||
|
||||
```bash
|
||||
# L'user doit être dans video et render
|
||||
ssh g01 "groups ansible"
|
||||
|
||||
# Si absent — ajouter manuellement
|
||||
ssh g01 "sudo usermod -aG video,render ansible"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Debug ROCm / llama-server
|
||||
|
||||
```bash
|
||||
# Tester OpenCL
|
||||
ssh g01 "HSA_OVERRIDE_GFX_VERSION=10.3.0 clinfo | head -30"
|
||||
|
||||
# Voir l'utilisation GPU en temps réel
|
||||
ssh g01 "watch -n 1 'cat /sys/class/drm/card*/device/gpu_busy_percent'"
|
||||
|
||||
# Température GPU
|
||||
ssh g01 "cat /sys/class/drm/card*/device/hwmon/hwmon*/temp1_input"
|
||||
# (valeur en millidegrés → diviser par 1000)
|
||||
|
||||
# VRAM utilisée
|
||||
ssh g01 "cat /sys/class/drm/card*/device/mem_info_vram_used"
|
||||
ssh g01 "cat /sys/class/drm/card*/device/mem_info_vram_total"
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue