11. Inférence Distante (Edge Computing)
ECHO intègre un pont d'inférence distante (Edge Embedding Bridge) permettant de déporter l'exécution du modèle de vectorisation microsoft/Harrier-OSS-v1-0.6B (GGUF) directement sur le matériel de l'utilisateur final. Ce système tire parti des capacités de la carte graphique du client (WebGPU) via un pont WebAssembly (WASM), allégeant significativement la charge CPU sur l'infrastructure hébergeant le framework.
Architecture du Pont WebGPU
Le mécanisme de pont s'appuie sur une interaction synchrone entre un filtre Open WebUI (le Côté Client) et le Worker d'Embedding (le Côté Serveur). Le processus se décompose en plusieurs étapes gérées de façon transparente pour l'utilisateur.
1. Injection du Payload (edge_embed_bridge_filter.py)
Le filtre edge_embed_bridge_filter.py intercepte la construction de l'interface graphique. Il injecte un module JavaScript (<script type="module">) directement dans la balise <body> de l'application. Ce script contient la logique de chargement de la bibliothèque Transformers.js et télécharge les poids du modèle Xenova/Harrier-OSS-v1-0.6B de manière asynchrone dans le navigateur.
2. Connexion WebSocket (/ws/edge-embed)
Une fois le script injecté, le client initie une connexion WebSocket vers le Worker d'Embedding sur l'endpoint /ws/edge-embed, en transmettant son jeton d'authentification (JWT). Le Worker authentifie la connexion et enregistre le client dans la liste des nœuds de calcul disponibles (active_edge_clients).
3. Boucle d'Attente Active
Avant de libérer la requête HTTP initiale, le filtre vérifie si la valve WAIT_FOR_EDGE_EMBEDDING est active. Si oui, il interroge le Worker (via l'API /internal/edge-status). Il exige un premier signe de vie dans une fenêtre stricte de 3 secondes (faute de quoi l'attente est annulée). Si le client répond, le filtre bloque le flux et attend que le statut passe à ready (modèle chargé en RAM GPU), dans la limite de temps maximale définie par la valve EDGE_EMBEDDING_TIMEOUT (défaut 180s). Dès que le client est prêt, l'interface graphique est affichée.
Processus de Vectorisation
Lorsqu'une demande de vectorisation (RAG, mémorisation) survient au sein de la boucle cognitive, ECHO dirige la requête vers le Worker d'Embedding (port 7997).
- Le Worker vérifie si le
user_idpossède un WebSocket actif dont le statut estready. - Si tel est le cas, le Worker envoie un message JSON contenant le texte à vectoriser (payload :
{ action: "embed", text: "...", task_type: "retrieval_document" }) vers le navigateur client. - Le navigateur utilise WebGPU (ou WebGL en cas de non-support) pour exécuter l'inférence via l'environnement WASM de Transformers.js.
- Le navigateur renvoie les 1024 vecteurs normalisés (L2) au Worker via WebSocket (payload :
{ status: "success", embedding: [...] }). - Le Worker transmet la réponse finale à la base vectorielle Qdrant.
Mécanisme de Repli (Fallback CPU)
La robustesse du framework exige que le système puisse fonctionner même si le navigateur de l'utilisateur n'est pas en mesure de traiter l'inférence. Le Worker d'Embedding intègre un mécanisme de Fallback CPU Synchrone (géré dans app.py).
Le repli CPU s'active immédiatement dans les scénarios suivants :
- Incompatibilité matérielle : Le client envoie un statut
incompatiblevia le WebSocket s'il ne peut initialiser le contexte WebGPU/WASM. - Déconnexion : Le client a fermé l'onglet ou la connexion WebSocket est perdue.
- Timeout Strict : Si le navigateur met plus de 15 secondes à retourner les vecteurs après une requête d'inférence, le Worker annule l'attente asynchrone et bascule instantanément sur l'exécution locale du modèle (via Llama.cpp) sur le CPU du serveur hôte.